mirror of
https://github.com/Cuprate/cuprate.git
synced 2024-12-23 03:59:31 +00:00
cuprated: initial RPC module skeleton (#262)
* readme * cuprated: add all workspace deps * cuprated: add lints * !! * add state, fn signatures * fixes * error signatures * interface: handle json-rpc concepts * split rpc calls into 3 `Service`s * interface: extract out to `RpcService` * fix merge * remove crate lints * use `BoxFuture` * rpc/interface: impl `thiserror::Error` * split state from main handler struct * cleanup * fix imports * replace `RpcError` with `anyhow::Error` * interface: update error * cuprated: update error type
This commit is contained in:
parent
4653ac5884
commit
92800810d9
21 changed files with 956 additions and 69 deletions
78
Cargo.lock
generated
78
Cargo.lock
generated
|
@ -56,6 +56,12 @@ version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "anyhow"
|
||||||
|
version = "1.0.87"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-stream"
|
name = "async-stream"
|
||||||
version = "0.3.5"
|
version = "0.3.5"
|
||||||
|
@ -799,6 +805,7 @@ dependencies = [
|
||||||
name = "cuprate-rpc-interface"
|
name = "cuprate-rpc-interface"
|
||||||
version = "0.0.0"
|
version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
"axum",
|
"axum",
|
||||||
"cuprate-epee-encoding",
|
"cuprate-epee-encoding",
|
||||||
"cuprate-helper",
|
"cuprate-helper",
|
||||||
|
@ -908,6 +915,68 @@ dependencies = [
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cuprated"
|
name = "cuprated"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"anyhow",
|
||||||
|
"async-trait",
|
||||||
|
"bitflags 2.5.0",
|
||||||
|
"borsh",
|
||||||
|
"bytemuck",
|
||||||
|
"bytes",
|
||||||
|
"cfg-if",
|
||||||
|
"chrono",
|
||||||
|
"clap",
|
||||||
|
"crossbeam",
|
||||||
|
"crypto-bigint",
|
||||||
|
"cuprate-address-book",
|
||||||
|
"cuprate-async-buffer",
|
||||||
|
"cuprate-blockchain",
|
||||||
|
"cuprate-consensus",
|
||||||
|
"cuprate-consensus-rules",
|
||||||
|
"cuprate-cryptonight",
|
||||||
|
"cuprate-dandelion-tower",
|
||||||
|
"cuprate-database",
|
||||||
|
"cuprate-database-service",
|
||||||
|
"cuprate-epee-encoding",
|
||||||
|
"cuprate-fast-sync",
|
||||||
|
"cuprate-fixed-bytes",
|
||||||
|
"cuprate-helper",
|
||||||
|
"cuprate-json-rpc",
|
||||||
|
"cuprate-levin",
|
||||||
|
"cuprate-p2p",
|
||||||
|
"cuprate-p2p-core",
|
||||||
|
"cuprate-pruning",
|
||||||
|
"cuprate-rpc-interface",
|
||||||
|
"cuprate-rpc-types",
|
||||||
|
"cuprate-test-utils",
|
||||||
|
"cuprate-txpool",
|
||||||
|
"cuprate-types",
|
||||||
|
"cuprate-wire",
|
||||||
|
"curve25519-dalek",
|
||||||
|
"dashmap",
|
||||||
|
"dirs",
|
||||||
|
"futures",
|
||||||
|
"hex",
|
||||||
|
"hex-literal",
|
||||||
|
"indexmap",
|
||||||
|
"monero-serai",
|
||||||
|
"paste",
|
||||||
|
"pin-project",
|
||||||
|
"rand",
|
||||||
|
"rand_distr",
|
||||||
|
"randomx-rs",
|
||||||
|
"rayon",
|
||||||
|
"serde",
|
||||||
|
"serde_bytes",
|
||||||
|
"serde_json",
|
||||||
|
"thiserror",
|
||||||
|
"thread_local",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tokio-util",
|
||||||
|
"tower",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "curve25519-dalek"
|
name = "curve25519-dalek"
|
||||||
|
@ -2503,6 +2572,15 @@ dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_bytes"
|
||||||
|
version = "0.11.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "387cc504cb06bb40a96c8e04e951fe01854cf6bc921053c954e4a606d9675c6a"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.203"
|
version = "1.0.203"
|
||||||
|
|
|
@ -48,6 +48,7 @@ opt-level = 1
|
||||||
opt-level = 3
|
opt-level = 3
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
|
anyhow = { version = "1.0.87", default-features = false }
|
||||||
async-trait = { version = "0.1.74", default-features = false }
|
async-trait = { version = "0.1.74", default-features = false }
|
||||||
bitflags = { version = "2.4.2", default-features = false }
|
bitflags = { version = "2.4.2", default-features = false }
|
||||||
borsh = { version = "1.2.1", default-features = false }
|
borsh = { version = "1.2.1", default-features = false }
|
||||||
|
|
|
@ -8,6 +8,69 @@ authors = ["Boog900", "hinto-janai", "SyntheticBird45"]
|
||||||
repository = "https://github.com/Cuprate/cuprate/tree/main/binaries/cuprated"
|
repository = "https://github.com/Cuprate/cuprate/tree/main/binaries/cuprated"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# TODO: after v1.0.0, remove unneeded dependencies.
|
||||||
|
cuprate-consensus = { path = "../../consensus" }
|
||||||
|
cuprate-fast-sync = { path = "../../consensus/fast-sync" }
|
||||||
|
cuprate-consensus-rules = { path = "../../consensus/rules" }
|
||||||
|
cuprate-cryptonight = { path = "../../cryptonight" }
|
||||||
|
cuprate-helper = { path = "../../helper" }
|
||||||
|
cuprate-epee-encoding = { path = "../../net/epee-encoding" }
|
||||||
|
cuprate-fixed-bytes = { path = "../../net/fixed-bytes" }
|
||||||
|
cuprate-levin = { path = "../../net/levin" }
|
||||||
|
cuprate-wire = { path = "../../net/wire" }
|
||||||
|
cuprate-p2p = { path = "../../p2p/p2p" }
|
||||||
|
cuprate-p2p-core = { path = "../../p2p/p2p-core" }
|
||||||
|
cuprate-dandelion-tower = { path = "../../p2p/dandelion-tower" }
|
||||||
|
cuprate-async-buffer = { path = "../../p2p/async-buffer" }
|
||||||
|
cuprate-address-book = { path = "../../p2p/address-book" }
|
||||||
|
cuprate-blockchain = { path = "../../storage/blockchain" }
|
||||||
|
cuprate-database-service = { path = "../../storage/service" }
|
||||||
|
cuprate-txpool = { path = "../../storage/txpool" }
|
||||||
|
cuprate-database = { path = "../../storage/database" }
|
||||||
|
cuprate-pruning = { path = "../../pruning" }
|
||||||
|
cuprate-test-utils = { path = "../../test-utils" }
|
||||||
|
cuprate-types = { path = "../../types" }
|
||||||
|
cuprate-json-rpc = { path = "../../rpc/json-rpc" }
|
||||||
|
cuprate-rpc-interface = { path = "../../rpc/interface" }
|
||||||
|
cuprate-rpc-types = { path = "../../rpc/types" }
|
||||||
|
|
||||||
|
# TODO: after v1.0.0, remove unneeded dependencies.
|
||||||
|
anyhow = { workspace = true }
|
||||||
|
async-trait = { workspace = true }
|
||||||
|
bitflags = { workspace = true }
|
||||||
|
borsh = { workspace = true }
|
||||||
|
bytemuck = { workspace = true }
|
||||||
|
bytes = { workspace = true }
|
||||||
|
cfg-if = { workspace = true }
|
||||||
|
clap = { workspace = true }
|
||||||
|
chrono = { workspace = true }
|
||||||
|
crypto-bigint = { workspace = true }
|
||||||
|
crossbeam = { workspace = true }
|
||||||
|
curve25519-dalek = { workspace = true }
|
||||||
|
dashmap = { workspace = true }
|
||||||
|
dirs = { workspace = true }
|
||||||
|
futures = { workspace = true }
|
||||||
|
hex = { workspace = true }
|
||||||
|
hex-literal = { workspace = true }
|
||||||
|
indexmap = { workspace = true }
|
||||||
|
monero-serai = { workspace = true }
|
||||||
|
paste = { workspace = true }
|
||||||
|
pin-project = { workspace = true }
|
||||||
|
randomx-rs = { workspace = true }
|
||||||
|
rand = { workspace = true }
|
||||||
|
rand_distr = { workspace = true }
|
||||||
|
rayon = { workspace = true }
|
||||||
|
serde_bytes = { workspace = true }
|
||||||
|
serde_json = { workspace = true }
|
||||||
|
serde = { workspace = true }
|
||||||
|
thiserror = { workspace = true }
|
||||||
|
thread_local = { workspace = true }
|
||||||
|
tokio-util = { workspace = true }
|
||||||
|
tokio-stream = { workspace = true }
|
||||||
|
tokio = { workspace = true }
|
||||||
|
tower = { workspace = true }
|
||||||
|
tracing-subscriber = { workspace = true }
|
||||||
|
tracing = { workspace = true }
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|
2
binaries/cuprated/README.md
Normal file
2
binaries/cuprated/README.md
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
# `cuprated`
|
||||||
|
TODO
|
|
@ -1,3 +1,16 @@
|
||||||
|
#![doc = include_str!("../README.md")]
|
||||||
|
#![cfg_attr(docsrs, feature(doc_cfg))]
|
||||||
|
#![allow(
|
||||||
|
unused_imports,
|
||||||
|
unreachable_pub,
|
||||||
|
unused_crate_dependencies,
|
||||||
|
dead_code,
|
||||||
|
unused_variables,
|
||||||
|
clippy::needless_pass_by_value,
|
||||||
|
clippy::unused_async,
|
||||||
|
reason = "TODO: remove after v1.0.0"
|
||||||
|
)]
|
||||||
|
|
||||||
mod blockchain;
|
mod blockchain;
|
||||||
mod config;
|
mod config;
|
||||||
mod p2p;
|
mod p2p;
|
||||||
|
|
|
@ -2,4 +2,9 @@
|
||||||
//!
|
//!
|
||||||
//! Will contain the code to initiate the RPC and a request handler.
|
//! Will contain the code to initiate the RPC and a request handler.
|
||||||
|
|
||||||
mod request_handler;
|
mod bin;
|
||||||
|
mod handler;
|
||||||
|
mod json;
|
||||||
|
mod other;
|
||||||
|
|
||||||
|
pub use handler::{CupratedRpcHandler, CupratedRpcHandlerState};
|
||||||
|
|
85
binaries/cuprated/src/rpc/bin.rs
Normal file
85
binaries/cuprated/src/rpc/bin.rs
Normal file
|
@ -0,0 +1,85 @@
|
||||||
|
use anyhow::Error;
|
||||||
|
|
||||||
|
use cuprate_rpc_types::{
|
||||||
|
bin::{
|
||||||
|
BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksByHeightResponse,
|
||||||
|
GetBlocksRequest, GetBlocksResponse, GetHashesRequest, GetHashesResponse,
|
||||||
|
GetOutputIndexesRequest, GetOutputIndexesResponse, GetOutsRequest, GetOutsResponse,
|
||||||
|
GetTransactionPoolHashesRequest, GetTransactionPoolHashesResponse,
|
||||||
|
},
|
||||||
|
json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::rpc::CupratedRpcHandlerState;
|
||||||
|
|
||||||
|
/// Map a [`BinRequest`] to the function that will lead to a [`BinResponse`].
|
||||||
|
pub(super) async fn map_request(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: BinRequest,
|
||||||
|
) -> Result<BinResponse, Error> {
|
||||||
|
use BinRequest as Req;
|
||||||
|
use BinResponse as Resp;
|
||||||
|
|
||||||
|
Ok(match request {
|
||||||
|
Req::GetBlocks(r) => Resp::GetBlocks(get_blocks(state, r).await?),
|
||||||
|
Req::GetBlocksByHeight(r) => Resp::GetBlocksByHeight(get_blocks_by_height(state, r).await?),
|
||||||
|
Req::GetHashes(r) => Resp::GetHashes(get_hashes(state, r).await?),
|
||||||
|
Req::GetOutputIndexes(r) => Resp::GetOutputIndexes(get_output_indexes(state, r).await?),
|
||||||
|
Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r).await?),
|
||||||
|
Req::GetTransactionPoolHashes(r) => {
|
||||||
|
Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetOutputDistribution(r) => {
|
||||||
|
Resp::GetOutputDistribution(get_output_distribution(state, r).await?)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_blocks(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBlocksRequest,
|
||||||
|
) -> Result<GetBlocksResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_blocks_by_height(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBlocksByHeightRequest,
|
||||||
|
) -> Result<GetBlocksByHeightResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_hashes(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetHashesRequest,
|
||||||
|
) -> Result<GetHashesResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_output_indexes(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetOutputIndexesRequest,
|
||||||
|
) -> Result<GetOutputIndexesResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_outs(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetOutsRequest,
|
||||||
|
) -> Result<GetOutsResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_transaction_pool_hashes(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetTransactionPoolHashesRequest,
|
||||||
|
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_output_distribution(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetOutputDistributionRequest,
|
||||||
|
) -> Result<GetOutputDistributionResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
103
binaries/cuprated/src/rpc/handler.rs
Normal file
103
binaries/cuprated/src/rpc/handler.rs
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
//! Dummy implementation of [`RpcHandler`].
|
||||||
|
|
||||||
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
|
use anyhow::Error;
|
||||||
|
use futures::{channel::oneshot::channel, future::BoxFuture};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use tower::Service;
|
||||||
|
|
||||||
|
use cuprate_blockchain::service::BlockchainReadHandle;
|
||||||
|
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||||
|
use cuprate_json_rpc::Id;
|
||||||
|
use cuprate_rpc_interface::RpcHandler;
|
||||||
|
use cuprate_rpc_types::{
|
||||||
|
bin::{BinRequest, BinResponse},
|
||||||
|
json::{JsonRpcRequest, JsonRpcResponse},
|
||||||
|
other::{OtherRequest, OtherResponse},
|
||||||
|
};
|
||||||
|
use cuprate_txpool::service::TxpoolReadHandle;
|
||||||
|
|
||||||
|
use crate::rpc::{bin, json, other};
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CupratedRpcHandler {
|
||||||
|
/// Should this RPC server be [restricted](RpcHandler::restricted)?
|
||||||
|
//
|
||||||
|
// INVARIANT:
|
||||||
|
// We don't need to include this in `state` and check for
|
||||||
|
// `self.is_restricted()` because `cuprate-rpc-interface` handles that.
|
||||||
|
pub restricted: bool,
|
||||||
|
|
||||||
|
/// State needed for request -> response mapping.
|
||||||
|
pub state: CupratedRpcHandlerState,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct CupratedRpcHandlerState {
|
||||||
|
/// Read handle to the blockchain database.
|
||||||
|
pub blockchain: BlockchainReadHandle,
|
||||||
|
|
||||||
|
/// Read handle to the transaction pool database.
|
||||||
|
pub txpool: TxpoolReadHandle,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CupratedRpcHandler {
|
||||||
|
/// TODO
|
||||||
|
pub fn init() {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RpcHandler for CupratedRpcHandler {
|
||||||
|
fn restricted(&self) -> bool {
|
||||||
|
self.restricted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Service<JsonRpcRequest> for CupratedRpcHandler {
|
||||||
|
type Response = JsonRpcResponse;
|
||||||
|
type Error = Error;
|
||||||
|
type Future = BoxFuture<'static, Result<JsonRpcResponse, Error>>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, request: JsonRpcRequest) -> Self::Future {
|
||||||
|
let state = CupratedRpcHandlerState::clone(&self.state);
|
||||||
|
Box::pin(json::map_request(state, request))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Service<BinRequest> for CupratedRpcHandler {
|
||||||
|
type Response = BinResponse;
|
||||||
|
type Error = Error;
|
||||||
|
type Future = BoxFuture<'static, Result<BinResponse, Error>>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, request: BinRequest) -> Self::Future {
|
||||||
|
let state = CupratedRpcHandlerState::clone(&self.state);
|
||||||
|
Box::pin(bin::map_request(state, request))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Service<OtherRequest> for CupratedRpcHandler {
|
||||||
|
type Response = OtherResponse;
|
||||||
|
type Error = Error;
|
||||||
|
type Future = BoxFuture<'static, Result<OtherResponse, Error>>;
|
||||||
|
|
||||||
|
fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
|
Poll::Ready(Ok(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn call(&mut self, request: OtherRequest) -> Self::Future {
|
||||||
|
let state = CupratedRpcHandlerState::clone(&self.state);
|
||||||
|
Box::pin(other::map_request(state, request))
|
||||||
|
}
|
||||||
|
}
|
294
binaries/cuprated/src/rpc/json.rs
Normal file
294
binaries/cuprated/src/rpc/json.rs
Normal file
|
@ -0,0 +1,294 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use anyhow::Error;
|
||||||
|
use tower::ServiceExt;
|
||||||
|
|
||||||
|
use cuprate_rpc_types::json::{
|
||||||
|
AddAuxPowRequest, AddAuxPowResponse, BannedRequest, BannedResponse, CalcPowRequest,
|
||||||
|
CalcPowResponse, FlushCacheRequest, FlushCacheResponse, FlushTransactionPoolRequest,
|
||||||
|
FlushTransactionPoolResponse, GenerateBlocksRequest, GenerateBlocksResponse,
|
||||||
|
GetAlternateChainsRequest, GetAlternateChainsResponse, GetBansRequest, GetBansResponse,
|
||||||
|
GetBlockCountRequest, GetBlockCountResponse, GetBlockHeaderByHashRequest,
|
||||||
|
GetBlockHeaderByHashResponse, GetBlockHeaderByHeightRequest, GetBlockHeaderByHeightResponse,
|
||||||
|
GetBlockHeadersRangeRequest, GetBlockHeadersRangeResponse, GetBlockRequest, GetBlockResponse,
|
||||||
|
GetCoinbaseTxSumRequest, GetCoinbaseTxSumResponse, GetConnectionsRequest,
|
||||||
|
GetConnectionsResponse, GetFeeEstimateRequest, GetFeeEstimateResponse, GetInfoRequest,
|
||||||
|
GetInfoResponse, GetLastBlockHeaderRequest, GetLastBlockHeaderResponse, GetMinerDataRequest,
|
||||||
|
GetMinerDataResponse, GetOutputHistogramRequest, GetOutputHistogramResponse,
|
||||||
|
GetTransactionPoolBacklogRequest, GetTransactionPoolBacklogResponse, GetTxIdsLooseRequest,
|
||||||
|
GetTxIdsLooseResponse, GetVersionRequest, GetVersionResponse, HardForkInfoRequest,
|
||||||
|
HardForkInfoResponse, JsonRpcRequest, JsonRpcResponse, OnGetBlockHashRequest,
|
||||||
|
OnGetBlockHashResponse, PruneBlockchainRequest, PruneBlockchainResponse, RelayTxRequest,
|
||||||
|
RelayTxResponse, SetBansRequest, SetBansResponse, SubmitBlockRequest, SubmitBlockResponse,
|
||||||
|
SyncInfoRequest, SyncInfoResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::rpc::CupratedRpcHandlerState;
|
||||||
|
|
||||||
|
/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`].
|
||||||
|
pub(super) async fn map_request(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: JsonRpcRequest,
|
||||||
|
) -> Result<JsonRpcResponse, Error> {
|
||||||
|
use JsonRpcRequest as Req;
|
||||||
|
use JsonRpcResponse as Resp;
|
||||||
|
|
||||||
|
Ok(match request {
|
||||||
|
Req::GetBlockCount(r) => Resp::GetBlockCount(get_block_count(state, r).await?),
|
||||||
|
Req::OnGetBlockHash(r) => Resp::OnGetBlockHash(on_get_block_hash(state, r).await?),
|
||||||
|
Req::SubmitBlock(r) => Resp::SubmitBlock(submit_block(state, r).await?),
|
||||||
|
Req::GenerateBlocks(r) => Resp::GenerateBlocks(generate_blocks(state, r).await?),
|
||||||
|
Req::GetLastBlockHeader(r) => {
|
||||||
|
Resp::GetLastBlockHeader(get_last_block_header(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetBlockHeaderByHash(r) => {
|
||||||
|
Resp::GetBlockHeaderByHash(get_block_header_by_hash(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetBlockHeaderByHeight(r) => {
|
||||||
|
Resp::GetBlockHeaderByHeight(get_block_header_by_height(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetBlockHeadersRange(r) => {
|
||||||
|
Resp::GetBlockHeadersRange(get_block_headers_range(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetBlock(r) => Resp::GetBlock(get_block(state, r).await?),
|
||||||
|
Req::GetConnections(r) => Resp::GetConnections(get_connections(state, r).await?),
|
||||||
|
Req::GetInfo(r) => Resp::GetInfo(get_info(state, r).await?),
|
||||||
|
Req::HardForkInfo(r) => Resp::HardForkInfo(hard_fork_info(state, r).await?),
|
||||||
|
Req::SetBans(r) => Resp::SetBans(set_bans(state, r).await?),
|
||||||
|
Req::GetBans(r) => Resp::GetBans(get_bans(state, r).await?),
|
||||||
|
Req::Banned(r) => Resp::Banned(banned(state, r).await?),
|
||||||
|
Req::FlushTransactionPool(r) => {
|
||||||
|
Resp::FlushTransactionPool(flush_transaction_pool(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetOutputHistogram(r) => {
|
||||||
|
Resp::GetOutputHistogram(get_output_histogram(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetCoinbaseTxSum(r) => Resp::GetCoinbaseTxSum(get_coinbase_tx_sum(state, r).await?),
|
||||||
|
Req::GetVersion(r) => Resp::GetVersion(get_version(state, r).await?),
|
||||||
|
Req::GetFeeEstimate(r) => Resp::GetFeeEstimate(get_fee_estimate(state, r).await?),
|
||||||
|
Req::GetAlternateChains(r) => {
|
||||||
|
Resp::GetAlternateChains(get_alternate_chains(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::RelayTx(r) => Resp::RelayTx(relay_tx(state, r).await?),
|
||||||
|
Req::SyncInfo(r) => Resp::SyncInfo(sync_info(state, r).await?),
|
||||||
|
Req::GetTransactionPoolBacklog(r) => {
|
||||||
|
Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r).await?),
|
||||||
|
Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r).await?),
|
||||||
|
Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r).await?),
|
||||||
|
Req::FlushCache(r) => Resp::FlushCache(flush_cache(state, r).await?),
|
||||||
|
Req::AddAuxPow(r) => Resp::AddAuxPow(add_aux_pow(state, r).await?),
|
||||||
|
Req::GetTxIdsLoose(r) => Resp::GetTxIdsLoose(get_tx_ids_loose(state, r).await?),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block_count(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBlockCountRequest,
|
||||||
|
) -> Result<GetBlockCountResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_get_block_hash(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: OnGetBlockHashRequest,
|
||||||
|
) -> Result<OnGetBlockHashResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn submit_block(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SubmitBlockRequest,
|
||||||
|
) -> Result<SubmitBlockResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn generate_blocks(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GenerateBlocksRequest,
|
||||||
|
) -> Result<GenerateBlocksResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_last_block_header(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetLastBlockHeaderRequest,
|
||||||
|
) -> Result<GetLastBlockHeaderResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block_header_by_hash(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBlockHeaderByHashRequest,
|
||||||
|
) -> Result<GetBlockHeaderByHashResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block_header_by_height(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBlockHeaderByHeightRequest,
|
||||||
|
) -> Result<GetBlockHeaderByHeightResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block_headers_range(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBlockHeadersRangeRequest,
|
||||||
|
) -> Result<GetBlockHeadersRangeResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_block(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBlockRequest,
|
||||||
|
) -> Result<GetBlockResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_connections(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetConnectionsRequest,
|
||||||
|
) -> Result<GetConnectionsResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_info(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetInfoRequest,
|
||||||
|
) -> Result<GetInfoResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn hard_fork_info(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: HardForkInfoRequest,
|
||||||
|
) -> Result<HardForkInfoResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_bans(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SetBansRequest,
|
||||||
|
) -> Result<SetBansResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_bans(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetBansRequest,
|
||||||
|
) -> Result<GetBansResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn banned(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: BannedRequest,
|
||||||
|
) -> Result<BannedResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn flush_transaction_pool(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: FlushTransactionPoolRequest,
|
||||||
|
) -> Result<FlushTransactionPoolResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_output_histogram(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetOutputHistogramRequest,
|
||||||
|
) -> Result<GetOutputHistogramResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_coinbase_tx_sum(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetCoinbaseTxSumRequest,
|
||||||
|
) -> Result<GetCoinbaseTxSumResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_version(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetVersionRequest,
|
||||||
|
) -> Result<GetVersionResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_fee_estimate(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetFeeEstimateRequest,
|
||||||
|
) -> Result<GetFeeEstimateResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_alternate_chains(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetAlternateChainsRequest,
|
||||||
|
) -> Result<GetAlternateChainsResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn relay_tx(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: RelayTxRequest,
|
||||||
|
) -> Result<RelayTxResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn sync_info(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SyncInfoRequest,
|
||||||
|
) -> Result<SyncInfoResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_transaction_pool_backlog(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetTransactionPoolBacklogRequest,
|
||||||
|
) -> Result<GetTransactionPoolBacklogResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_miner_data(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetMinerDataRequest,
|
||||||
|
) -> Result<GetMinerDataResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn prune_blockchain(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: PruneBlockchainRequest,
|
||||||
|
) -> Result<PruneBlockchainResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn calc_pow(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: CalcPowRequest,
|
||||||
|
) -> Result<CalcPowResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn flush_cache(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: FlushCacheRequest,
|
||||||
|
) -> Result<FlushCacheResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn add_aux_pow(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: AddAuxPowRequest,
|
||||||
|
) -> Result<AddAuxPowResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_tx_ids_loose(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetTxIdsLooseRequest,
|
||||||
|
) -> Result<GetTxIdsLooseResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
260
binaries/cuprated/src/rpc/other.rs
Normal file
260
binaries/cuprated/src/rpc/other.rs
Normal file
|
@ -0,0 +1,260 @@
|
||||||
|
use anyhow::Error;
|
||||||
|
|
||||||
|
use cuprate_rpc_types::other::{
|
||||||
|
GetAltBlocksHashesRequest, GetAltBlocksHashesResponse, GetHeightRequest, GetHeightResponse,
|
||||||
|
GetLimitRequest, GetLimitResponse, GetNetStatsRequest, GetNetStatsResponse, GetOutsRequest,
|
||||||
|
GetOutsResponse, GetPeerListRequest, GetPeerListResponse, GetPublicNodesRequest,
|
||||||
|
GetPublicNodesResponse, GetTransactionPoolHashesRequest, GetTransactionPoolHashesResponse,
|
||||||
|
GetTransactionPoolRequest, GetTransactionPoolResponse, GetTransactionPoolStatsRequest,
|
||||||
|
GetTransactionPoolStatsResponse, GetTransactionsRequest, GetTransactionsResponse,
|
||||||
|
InPeersRequest, InPeersResponse, IsKeyImageSpentRequest, IsKeyImageSpentResponse,
|
||||||
|
MiningStatusRequest, MiningStatusResponse, OtherRequest, OtherResponse, OutPeersRequest,
|
||||||
|
OutPeersResponse, PopBlocksRequest, PopBlocksResponse, SaveBcRequest, SaveBcResponse,
|
||||||
|
SendRawTransactionRequest, SendRawTransactionResponse, SetBootstrapDaemonRequest,
|
||||||
|
SetBootstrapDaemonResponse, SetLimitRequest, SetLimitResponse, SetLogCategoriesRequest,
|
||||||
|
SetLogCategoriesResponse, SetLogHashRateRequest, SetLogHashRateResponse, SetLogLevelRequest,
|
||||||
|
SetLogLevelResponse, StartMiningRequest, StartMiningResponse, StopDaemonRequest,
|
||||||
|
StopDaemonResponse, StopMiningRequest, StopMiningResponse, UpdateRequest, UpdateResponse,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::rpc::CupratedRpcHandlerState;
|
||||||
|
|
||||||
|
/// Map a [`OtherRequest`] to the function that will lead to a [`OtherResponse`].
|
||||||
|
pub(super) async fn map_request(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: OtherRequest,
|
||||||
|
) -> Result<OtherResponse, Error> {
|
||||||
|
use OtherRequest as Req;
|
||||||
|
use OtherResponse as Resp;
|
||||||
|
|
||||||
|
Ok(match request {
|
||||||
|
Req::GetHeight(r) => Resp::GetHeight(get_height(state, r).await?),
|
||||||
|
Req::GetTransactions(r) => Resp::GetTransactions(get_transactions(state, r).await?),
|
||||||
|
Req::GetAltBlocksHashes(r) => {
|
||||||
|
Resp::GetAltBlocksHashes(get_alt_blocks_hashes(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::IsKeyImageSpent(r) => Resp::IsKeyImageSpent(is_key_image_spent(state, r).await?),
|
||||||
|
Req::SendRawTransaction(r) => {
|
||||||
|
Resp::SendRawTransaction(send_raw_transaction(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::StartMining(r) => Resp::StartMining(start_mining(state, r).await?),
|
||||||
|
Req::StopMining(r) => Resp::StopMining(stop_mining(state, r).await?),
|
||||||
|
Req::MiningStatus(r) => Resp::MiningStatus(mining_status(state, r).await?),
|
||||||
|
Req::SaveBc(r) => Resp::SaveBc(save_bc(state, r).await?),
|
||||||
|
Req::GetPeerList(r) => Resp::GetPeerList(get_peer_list(state, r).await?),
|
||||||
|
Req::SetLogHashRate(r) => Resp::SetLogHashRate(set_log_hash_rate(state, r).await?),
|
||||||
|
Req::SetLogLevel(r) => Resp::SetLogLevel(set_log_level(state, r).await?),
|
||||||
|
Req::SetLogCategories(r) => Resp::SetLogCategories(set_log_categories(state, r).await?),
|
||||||
|
Req::SetBootstrapDaemon(r) => {
|
||||||
|
Resp::SetBootstrapDaemon(set_bootstrap_daemon(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetTransactionPool(r) => {
|
||||||
|
Resp::GetTransactionPool(get_transaction_pool(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetTransactionPoolStats(r) => {
|
||||||
|
Resp::GetTransactionPoolStats(get_transaction_pool_stats(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::StopDaemon(r) => Resp::StopDaemon(stop_daemon(state, r).await?),
|
||||||
|
Req::GetLimit(r) => Resp::GetLimit(get_limit(state, r).await?),
|
||||||
|
Req::SetLimit(r) => Resp::SetLimit(set_limit(state, r).await?),
|
||||||
|
Req::OutPeers(r) => Resp::OutPeers(out_peers(state, r).await?),
|
||||||
|
Req::InPeers(r) => Resp::InPeers(in_peers(state, r).await?),
|
||||||
|
Req::GetNetStats(r) => Resp::GetNetStats(get_net_stats(state, r).await?),
|
||||||
|
Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r).await?),
|
||||||
|
Req::Update(r) => Resp::Update(update(state, r).await?),
|
||||||
|
Req::PopBlocks(r) => Resp::PopBlocks(pop_blocks(state, r).await?),
|
||||||
|
Req::GetTransactionPoolHashes(r) => {
|
||||||
|
Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r).await?)
|
||||||
|
}
|
||||||
|
Req::GetPublicNodes(r) => Resp::GetPublicNodes(get_public_nodes(state, r).await?),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_height(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetHeightRequest,
|
||||||
|
) -> Result<GetHeightResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_transactions(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetTransactionsRequest,
|
||||||
|
) -> Result<GetTransactionsResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_alt_blocks_hashes(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetAltBlocksHashesRequest,
|
||||||
|
) -> Result<GetAltBlocksHashesResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn is_key_image_spent(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: IsKeyImageSpentRequest,
|
||||||
|
) -> Result<IsKeyImageSpentResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn send_raw_transaction(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SendRawTransactionRequest,
|
||||||
|
) -> Result<SendRawTransactionResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn start_mining(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: StartMiningRequest,
|
||||||
|
) -> Result<StartMiningResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn stop_mining(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: StopMiningRequest,
|
||||||
|
) -> Result<StopMiningResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn mining_status(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: MiningStatusRequest,
|
||||||
|
) -> Result<MiningStatusResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn save_bc(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SaveBcRequest,
|
||||||
|
) -> Result<SaveBcResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_peer_list(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetPeerListRequest,
|
||||||
|
) -> Result<GetPeerListResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_log_hash_rate(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SetLogHashRateRequest,
|
||||||
|
) -> Result<SetLogHashRateResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_log_level(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SetLogLevelRequest,
|
||||||
|
) -> Result<SetLogLevelResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_log_categories(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SetLogCategoriesRequest,
|
||||||
|
) -> Result<SetLogCategoriesResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_bootstrap_daemon(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SetBootstrapDaemonRequest,
|
||||||
|
) -> Result<SetBootstrapDaemonResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_transaction_pool(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetTransactionPoolRequest,
|
||||||
|
) -> Result<GetTransactionPoolResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_transaction_pool_stats(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetTransactionPoolStatsRequest,
|
||||||
|
) -> Result<GetTransactionPoolStatsResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn stop_daemon(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: StopDaemonRequest,
|
||||||
|
) -> Result<StopDaemonResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_limit(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetLimitRequest,
|
||||||
|
) -> Result<GetLimitResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn set_limit(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: SetLimitRequest,
|
||||||
|
) -> Result<SetLimitResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn out_peers(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: OutPeersRequest,
|
||||||
|
) -> Result<OutPeersResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn in_peers(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: InPeersRequest,
|
||||||
|
) -> Result<InPeersResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_net_stats(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetNetStatsRequest,
|
||||||
|
) -> Result<GetNetStatsResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_outs(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetOutsRequest,
|
||||||
|
) -> Result<GetOutsResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn update(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: UpdateRequest,
|
||||||
|
) -> Result<UpdateResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn pop_blocks(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: PopBlocksRequest,
|
||||||
|
) -> Result<PopBlocksResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_transaction_pool_hashes(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetTransactionPoolHashesRequest,
|
||||||
|
) -> Result<GetTransactionPoolHashesResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_public_nodes(
|
||||||
|
state: CupratedRpcHandlerState,
|
||||||
|
request: GetPublicNodesRequest,
|
||||||
|
) -> Result<GetPublicNodesResponse, Error> {
|
||||||
|
todo!()
|
||||||
|
}
|
|
@ -1 +0,0 @@
|
||||||
|
|
|
@ -18,6 +18,7 @@ cuprate-json-rpc = { path = "../json-rpc", default-features = false }
|
||||||
cuprate-rpc-types = { path = "../types", features = ["serde", "epee"], default-features = false }
|
cuprate-rpc-types = { path = "../types", features = ["serde", "epee"], default-features = false }
|
||||||
cuprate-helper = { path = "../../helper", features = ["asynch"], default-features = false }
|
cuprate-helper = { path = "../../helper", features = ["asynch"], default-features = false }
|
||||||
|
|
||||||
|
anyhow = { workspace = true }
|
||||||
axum = { version = "0.7.5", features = ["json"], default-features = false }
|
axum = { version = "0.7.5", features = ["json"], default-features = false }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
tower = { workspace = true }
|
tower = { workspace = true }
|
||||||
|
|
|
@ -45,15 +45,16 @@ The proper usage of this crate is to:
|
||||||
This is your [`tower::Service`] that converts `Request`s into `Response`s,
|
This is your [`tower::Service`] that converts `Request`s into `Response`s,
|
||||||
i.e. the "inner handler".
|
i.e. the "inner handler".
|
||||||
|
|
||||||
Said concretely, `RpcHandler` is 3 `tower::Service`s where the request/response types are
|
Said concretely, `RpcHandler` is 3 `tower::Service`s where the
|
||||||
the 3 endpoint enums from [`cuprate_rpc_types`] and the error type is from this crate:
|
request/response types are the 3 endpoint enums from [`cuprate_rpc_types`]:
|
||||||
- [`JsonRpcRequest`](cuprate_rpc_types::json::JsonRpcRequest) & [`JsonRpcResponse`](cuprate_rpc_types::json::JsonRpcResponse)
|
- [`JsonRpcRequest`](cuprate_rpc_types::json::JsonRpcRequest) & [`JsonRpcResponse`](cuprate_rpc_types::json::JsonRpcResponse)
|
||||||
- [`BinRequest`](cuprate_rpc_types::bin::BinRequest) & [`BinResponse`](cuprate_rpc_types::bin::BinRequest)
|
- [`BinRequest`](cuprate_rpc_types::bin::BinRequest) & [`BinResponse`](cuprate_rpc_types::bin::BinRequest)
|
||||||
- [`OtherRequest`](cuprate_rpc_types::other::OtherRequest) & [`OtherResponse`](cuprate_rpc_types::other::OtherRequest)
|
- [`OtherRequest`](cuprate_rpc_types::other::OtherRequest) & [`OtherResponse`](cuprate_rpc_types::other::OtherRequest)
|
||||||
- [`RpcError`]
|
|
||||||
|
|
||||||
`RpcHandler`'s [`Future`](std::future::Future) is generic, _although_,
|
`RpcHandler`'s [`Future`](std::future::Future) is generic, _although_,
|
||||||
it must output `Result<$RESPONSE, RpcError>`.
|
it must output `Result<$RESPONSE, anyhow::Error>`.
|
||||||
|
|
||||||
|
The error type must always be [`anyhow::Error`].
|
||||||
|
|
||||||
The `RpcHandler` must also hold some state that is required
|
The `RpcHandler` must also hold some state that is required
|
||||||
for RPC server operation.
|
for RPC server operation.
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
|
|
||||||
mod route;
|
mod route;
|
||||||
mod router_builder;
|
mod router_builder;
|
||||||
mod rpc_error;
|
|
||||||
mod rpc_handler;
|
mod rpc_handler;
|
||||||
#[cfg(feature = "dummy")]
|
#[cfg(feature = "dummy")]
|
||||||
mod rpc_handler_dummy;
|
mod rpc_handler_dummy;
|
||||||
mod rpc_service;
|
mod rpc_service;
|
||||||
|
|
||||||
pub use router_builder::RouterBuilder;
|
pub use router_builder::RouterBuilder;
|
||||||
pub use rpc_error::RpcError;
|
|
||||||
pub use rpc_handler::RpcHandler;
|
pub use rpc_handler::RpcHandler;
|
||||||
#[cfg(feature = "dummy")]
|
#[cfg(feature = "dummy")]
|
||||||
pub use rpc_handler_dummy::RpcHandlerDummy;
|
pub use rpc_handler_dummy::RpcHandlerDummy;
|
||||||
|
|
|
@ -5,7 +5,14 @@ use axum::{body::Bytes, extract::State, http::StatusCode};
|
||||||
use tower::ServiceExt;
|
use tower::ServiceExt;
|
||||||
|
|
||||||
use cuprate_epee_encoding::from_bytes;
|
use cuprate_epee_encoding::from_bytes;
|
||||||
use cuprate_rpc_types::bin::{BinRequest, BinResponse, GetTransactionPoolHashesRequest};
|
use cuprate_rpc_types::{
|
||||||
|
bin::{
|
||||||
|
BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksRequest, GetHashesRequest,
|
||||||
|
GetOutputIndexesRequest, GetOutsRequest, GetTransactionPoolHashesRequest,
|
||||||
|
},
|
||||||
|
json::GetOutputDistributionRequest,
|
||||||
|
RpcCall,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::rpc_handler::RpcHandler;
|
use crate::rpc_handler::RpcHandler;
|
||||||
|
|
||||||
|
@ -66,8 +73,16 @@ macro_rules! generate_endpoints_inner {
|
||||||
($variant:ident, $handler:ident, $request:expr) => {
|
($variant:ident, $handler:ident, $request:expr) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
{
|
{
|
||||||
|
// Check if restricted.
|
||||||
|
if [<$variant Request>]::IS_RESTRICTED && $handler.restricted() {
|
||||||
|
// TODO: mimic `monerod` behavior.
|
||||||
|
return Err(StatusCode::FORBIDDEN);
|
||||||
|
}
|
||||||
|
|
||||||
// Send request.
|
// Send request.
|
||||||
let response = $handler.oneshot($request).await?;
|
let Ok(response) = $handler.oneshot($request).await else {
|
||||||
|
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
};
|
||||||
|
|
||||||
let BinResponse::$variant(response) = response else {
|
let BinResponse::$variant(response) = response else {
|
||||||
panic!("RPC handler returned incorrect response");
|
panic!("RPC handler returned incorrect response");
|
||||||
|
|
|
@ -50,7 +50,9 @@ pub(crate) async fn json_rpc<H: RpcHandler>(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send request.
|
// Send request.
|
||||||
let response = handler.oneshot(request.body).await?;
|
let Ok(response) = handler.oneshot(request.body).await else {
|
||||||
|
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Json(Response::ok(id, response)))
|
Ok(Json(Response::ok(id, response)))
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,7 +82,9 @@ macro_rules! generate_endpoints_inner {
|
||||||
|
|
||||||
// Send request.
|
// Send request.
|
||||||
let request = OtherRequest::$variant($request);
|
let request = OtherRequest::$variant($request);
|
||||||
let response = $handler.oneshot(request).await?;
|
let Ok(response) = $handler.oneshot(request).await else {
|
||||||
|
return Err(StatusCode::INTERNAL_SERVER_ERROR);
|
||||||
|
};
|
||||||
|
|
||||||
let OtherResponse::$variant(response) = response else {
|
let OtherResponse::$variant(response) = response else {
|
||||||
panic!("RPC handler returned incorrect response")
|
panic!("RPC handler returned incorrect response")
|
||||||
|
|
|
@ -1,34 +0,0 @@
|
||||||
//! RPC errors.
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Import
|
|
||||||
use axum::http::StatusCode;
|
|
||||||
#[cfg(feature = "serde")]
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- RpcError
|
|
||||||
/// Possible errors during RPC operation.
|
|
||||||
///
|
|
||||||
/// These are any errors that can happen _during_ a handler function.
|
|
||||||
/// I.e. if this error surfaces, it happened _after_ the request was
|
|
||||||
/// deserialized.
|
|
||||||
///
|
|
||||||
/// This is the `Error` type required to be used in an [`RpcHandler`](crate::RpcHandler).
|
|
||||||
///
|
|
||||||
/// TODO: This is empty as possible errors will be
|
|
||||||
/// enumerated when the handler functions are created.
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
|
||||||
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
|
|
||||||
pub enum RpcError {}
|
|
||||||
|
|
||||||
impl From<RpcError> for StatusCode {
|
|
||||||
fn from(_: RpcError) -> Self {
|
|
||||||
// TODO
|
|
||||||
Self::INTERNAL_SERVER_ERROR
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Tests
|
|
||||||
#[cfg(test)]
|
|
||||||
mod test {
|
|
||||||
// use super::*;
|
|
||||||
}
|
|
|
@ -22,7 +22,7 @@ use crate::RpcService;
|
||||||
/// In other words, an [`RpcHandler`] is a type that implements [`tower::Service`] 3 times,
|
/// In other words, an [`RpcHandler`] is a type that implements [`tower::Service`] 3 times,
|
||||||
/// one for each request/response enum type found in [`cuprate_rpc_types`].
|
/// one for each request/response enum type found in [`cuprate_rpc_types`].
|
||||||
///
|
///
|
||||||
/// The error type must always be [`RpcError`](crate::RpcError).
|
/// The error type must always be [`anyhow::Error`].
|
||||||
///
|
///
|
||||||
/// See this crate's `RpcHandlerDummy` for an implementation example of this trait.
|
/// See this crate's `RpcHandlerDummy` for an implementation example of this trait.
|
||||||
///
|
///
|
||||||
|
|
|
@ -3,19 +3,20 @@
|
||||||
//---------------------------------------------------------------------------------------------------- Use
|
//---------------------------------------------------------------------------------------------------- Use
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
|
|
||||||
use cuprate_rpc_types::{
|
use anyhow::Error;
|
||||||
bin::{BinRequest, BinResponse},
|
|
||||||
json::{JsonRpcRequest, JsonRpcResponse},
|
|
||||||
other::{OtherRequest, OtherResponse},
|
|
||||||
};
|
|
||||||
use futures::channel::oneshot::channel;
|
use futures::channel::oneshot::channel;
|
||||||
#[cfg(feature = "serde")]
|
#[cfg(feature = "serde")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
|
||||||
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
use cuprate_helper::asynch::InfallibleOneshotReceiver;
|
||||||
|
use cuprate_rpc_types::{
|
||||||
|
bin::{BinRequest, BinResponse},
|
||||||
|
json::{JsonRpcRequest, JsonRpcResponse},
|
||||||
|
other::{OtherRequest, OtherResponse},
|
||||||
|
};
|
||||||
|
|
||||||
use crate::{rpc_error::RpcError, rpc_handler::RpcHandler};
|
use crate::rpc_handler::RpcHandler;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- RpcHandlerDummy
|
//---------------------------------------------------------------------------------------------------- RpcHandlerDummy
|
||||||
/// An [`RpcHandler`] that always returns [`Default::default`].
|
/// An [`RpcHandler`] that always returns [`Default::default`].
|
||||||
|
@ -45,8 +46,8 @@ impl RpcHandler for RpcHandlerDummy {
|
||||||
|
|
||||||
impl Service<JsonRpcRequest> for RpcHandlerDummy {
|
impl Service<JsonRpcRequest> for RpcHandlerDummy {
|
||||||
type Response = JsonRpcResponse;
|
type Response = JsonRpcResponse;
|
||||||
type Error = RpcError;
|
type Error = Error;
|
||||||
type Future = InfallibleOneshotReceiver<Result<JsonRpcResponse, RpcError>>;
|
type Future = InfallibleOneshotReceiver<Result<JsonRpcResponse, Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
|
@ -100,8 +101,8 @@ impl Service<JsonRpcRequest> for RpcHandlerDummy {
|
||||||
|
|
||||||
impl Service<BinRequest> for RpcHandlerDummy {
|
impl Service<BinRequest> for RpcHandlerDummy {
|
||||||
type Response = BinResponse;
|
type Response = BinResponse;
|
||||||
type Error = RpcError;
|
type Error = Error;
|
||||||
type Future = InfallibleOneshotReceiver<Result<BinResponse, RpcError>>;
|
type Future = InfallibleOneshotReceiver<Result<BinResponse, Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
|
@ -130,8 +131,8 @@ impl Service<BinRequest> for RpcHandlerDummy {
|
||||||
|
|
||||||
impl Service<OtherRequest> for RpcHandlerDummy {
|
impl Service<OtherRequest> for RpcHandlerDummy {
|
||||||
type Response = OtherResponse;
|
type Response = OtherResponse;
|
||||||
type Error = RpcError;
|
type Error = Error;
|
||||||
type Future = InfallibleOneshotReceiver<Result<OtherResponse, RpcError>>;
|
type Future = InfallibleOneshotReceiver<Result<OtherResponse, Error>>;
|
||||||
|
|
||||||
fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
|
||||||
Poll::Ready(Ok(()))
|
Poll::Ready(Ok(()))
|
||||||
|
|
|
@ -5,8 +5,6 @@ use std::future::Future;
|
||||||
|
|
||||||
use tower::Service;
|
use tower::Service;
|
||||||
|
|
||||||
use crate::rpc_error::RpcError;
|
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- RpcService
|
//---------------------------------------------------------------------------------------------------- RpcService
|
||||||
/// An RPC [`tower::Service`].
|
/// An RPC [`tower::Service`].
|
||||||
///
|
///
|
||||||
|
@ -17,7 +15,7 @@ use crate::rpc_error::RpcError;
|
||||||
/// The `Request` and `Response` are generic and
|
/// The `Request` and `Response` are generic and
|
||||||
/// are used in the [`tower::Service`] bounds.
|
/// are used in the [`tower::Service`] bounds.
|
||||||
///
|
///
|
||||||
/// The error type is always [`RpcError`].
|
/// The error type is always [`anyhow::Error`].
|
||||||
///
|
///
|
||||||
/// There is a blanket implementation that implements this
|
/// There is a blanket implementation that implements this
|
||||||
/// trait on types that implement `tower::Service` correctly.
|
/// trait on types that implement `tower::Service` correctly.
|
||||||
|
@ -31,8 +29,8 @@ pub trait RpcService<Request, Response>:
|
||||||
+ Service<
|
+ Service<
|
||||||
Request,
|
Request,
|
||||||
Response = Response,
|
Response = Response,
|
||||||
Error = RpcError,
|
Error = anyhow::Error,
|
||||||
Future: Future<Output = Result<Response, RpcError>> + Send + Sync + 'static,
|
Future: Future<Output = Result<Response, anyhow::Error>> + Send + 'static,
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -45,8 +43,8 @@ impl<Request, Response, T> RpcService<Request, Response> for T where
|
||||||
+ Service<
|
+ Service<
|
||||||
Request,
|
Request,
|
||||||
Response = Response,
|
Response = Response,
|
||||||
Error = RpcError,
|
Error = anyhow::Error,
|
||||||
Future: Future<Output = Result<Response, RpcError>> + Send + Sync + 'static,
|
Future: Future<Output = Result<Response, anyhow::Error>> + Send + 'static,
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue