From b28c52a8c0729b15f50b57b22294e3c55d2761e7 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Sun, 1 Sep 2024 16:33:23 -0400 Subject: [PATCH 01/20] readme --- binaries/cuprated/README.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 binaries/cuprated/README.md diff --git a/binaries/cuprated/README.md b/binaries/cuprated/README.md new file mode 100644 index 000000000..47f040800 --- /dev/null +++ b/binaries/cuprated/README.md @@ -0,0 +1,2 @@ +# `cuprated` +TODO From ac1815a8c96f43cc1b5e057554fbb2f837b6ec89 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Sun, 1 Sep 2024 16:37:40 -0400 Subject: [PATCH 02/20] cuprated: add all workspace deps --- Cargo.lock | 70 ++++++++++++++++++++++++++++++++++++ Cargo.toml | 2 +- binaries/cuprated/Cargo.toml | 62 ++++++++++++++++++++++++++++++++ 3 files changed, 133 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 77531897a..51d3020d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -902,6 +902,67 @@ dependencies = [ [[package]] name = "cuprated" version = "0.1.0" +dependencies = [ + "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]] name = "curve25519-dalek" @@ -2488,6 +2549,15 @@ dependencies = [ "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]] name = "serde_derive" version = "1.0.203" diff --git a/Cargo.toml b/Cargo.toml index 06b49a0a8..0142876f1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,7 +76,7 @@ serde_bytes = { version = "0.11.12", default-features = false } serde_json = { version = "1.0.108", default-features = false } serde = { version = "1.0.190", default-features = false } thiserror = { version = "1.0.50", default-features = false } -thread_local = { version = "1.1.7", default-features = false } +thread_local = { version = "1.1.7", default-features = false } tokio-util = { version = "0.7.10", default-features = false } tokio-stream = { version = "0.1.14", default-features = false } tokio = { version = "1.33.0", default-features = false } diff --git a/binaries/cuprated/Cargo.toml b/binaries/cuprated/Cargo.toml index b52439061..63a04317b 100644 --- a/binaries/cuprated/Cargo.toml +++ b/binaries/cuprated/Cargo.toml @@ -8,6 +8,68 @@ authors = ["Boog900", "hinto-janai", "SyntheticBird45"] repository = "https://github.com/Cuprate/cuprate/tree/main/binaries/cuprated" [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. +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] workspace = true From d83a93fc3135249a1b4be6c9cbc28b84c13cb57e Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Sun, 1 Sep 2024 16:38:17 -0400 Subject: [PATCH 03/20] cuprated: add lints --- binaries/cuprated/src/main.rs | 97 +++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index 918429c9a..a08f3d654 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -1,3 +1,100 @@ +#![doc = include_str!("../README.md")] +#![cfg_attr(docsrs, feature(doc_cfg))] +//---------------------------------------------------------------------------------------------------- Lints +// Forbid lints. +// Our code, and code generated (e.g macros) cannot overrule these. +#![forbid( + // `unsafe` is allowed but it _must_ be + // commented with `SAFETY: reason`. + clippy::undocumented_unsafe_blocks, + + // Never. + unused_unsafe, + redundant_semicolons, + unused_allocation, + coherence_leak_check, + while_true, + + // Maybe can be put into `#[deny]`. + unconditional_recursion, + for_loops_over_fallibles, + unused_braces, + unused_labels, + keyword_idents, + non_ascii_idents, + variant_size_differences, + single_use_lifetimes, + + // Probably can be put into `#[deny]`. + future_incompatible, + let_underscore, + break_with_label_and_loop, + duplicate_macro_attributes, + exported_private_dependencies, + large_assignments, + overlapping_range_endpoints, + semicolon_in_expressions_from_macros, + noop_method_call, +)] +// Deny lints. +// Some of these are `#[allow]`'ed on a per-case basis. +#![deny( + clippy::all, + clippy::correctness, + clippy::suspicious, + clippy::style, + clippy::complexity, + clippy::perf, + clippy::pedantic, + clippy::nursery, + clippy::cargo, + unused_doc_comments, + unused_mut, + missing_docs, + deprecated, + unused_comparisons, + nonstandard_style, + // unreachable_pub +)] +#![allow( + // FIXME: this lint affects crates outside of + // `database/` for some reason, allow for now. + clippy::cargo_common_metadata, + + // FIXME: adding `#[must_use]` onto everything + // might just be more annoying than useful... + // although it is sometimes nice. + clippy::must_use_candidate, + + // FIXME: good lint but too many false positives + // with our `Env` + `RwLock` setup. + clippy::significant_drop_tightening, + + // FIXME: good lint but is less clear in most cases. + clippy::items_after_statements, + + // TODO + rustdoc::bare_urls, + + clippy::multiple_crate_versions, + clippy::module_name_repetitions, + clippy::module_inception, + clippy::redundant_pub_crate, + clippy::option_if_let_else, +)] +// Allow some lints in tests. +#![cfg_attr( + test, + allow( + clippy::cognitive_complexity, + clippy::needless_pass_by_value, + clippy::cast_possible_truncation, + clippy::too_many_lines + ) +)] +// TODO: remove after debug and/or v1.0.0 impl. +#![allow(unused_imports, unreachable_pub, unused_crate_dependencies)] + mod blockchain; mod config; mod p2p; From 5b0e56f711876ae7c60eb2b2e000cbdb81cca58a Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Sun, 1 Sep 2024 16:59:33 -0400 Subject: [PATCH 04/20] !! --- binaries/cuprated/src/main.rs | 1 - binaries/cuprated/src/rpc.rs | 4 +- binaries/cuprated/src/rpc/handler.rs | 129 +++++++++++++++++++ binaries/cuprated/src/rpc/request_handler.rs | 1 - 4 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 binaries/cuprated/src/rpc/handler.rs delete mode 100644 binaries/cuprated/src/rpc/request_handler.rs diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index a08f3d654..9c59a5673 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -13,7 +13,6 @@ redundant_semicolons, unused_allocation, coherence_leak_check, - while_true, // Maybe can be put into `#[deny]`. unconditional_recursion, diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 80b2789ea..773da8073 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -2,4 +2,6 @@ //! //! Will contain the code to initiate the RPC and a request handler. -mod request_handler; +mod handler; + +pub use handler::CupratedRpcHandler; diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs new file mode 100644 index 000000000..fd17a1050 --- /dev/null +++ b/binaries/cuprated/src/rpc/handler.rs @@ -0,0 +1,129 @@ +//! Dummy implementation of [`RpcHandler`]. + +//---------------------------------------------------------------------------------------------------- Use +use std::task::Poll; + +use futures::channel::oneshot::channel; +use serde::{Deserialize, Serialize}; +use tower::Service; + +use cuprate_helper::asynch::InfallibleOneshotReceiver; +use cuprate_json_rpc::Id; +use cuprate_rpc_interface::{RpcError, RpcHandler, RpcRequest, RpcResponse}; + +//---------------------------------------------------------------------------------------------------- CupratedRpcHandler +/// TODO +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] +pub struct CupratedRpcHandler { + /// Should this RPC server be [restricted](RpcHandler::restricted)? + pub restricted: bool, +} + +impl RpcHandler for CupratedRpcHandler { + fn restricted(&self) -> bool { + self.restricted + } +} + +impl Service for CupratedRpcHandler { + type Response = RpcResponse; + type Error = RpcError; + type Future = InfallibleOneshotReceiver>; + + fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: RpcRequest) -> Self::Future { + use cuprate_rpc_types::bin::BinRequest as BReq; + use cuprate_rpc_types::bin::BinResponse as BResp; + use cuprate_rpc_types::json::JsonRpcRequest as JReq; + use cuprate_rpc_types::json::JsonRpcResponse as JResp; + use cuprate_rpc_types::other::OtherRequest as OReq; + use cuprate_rpc_types::other::OtherResponse as OResp; + + #[rustfmt::skip] + #[allow(clippy::default_trait_access)] + let resp = match req { + // JSON-RPC 2.0 requests. + RpcRequest::JsonRpc(j) => RpcResponse::JsonRpc(cuprate_json_rpc::Response::ok(Id::Null, match j.body { + JReq::GetBlockCount(_) => JResp::GetBlockCount(Default::default()), + JReq::OnGetBlockHash(_) => JResp::OnGetBlockHash(Default::default()), + JReq::SubmitBlock(_) => JResp::SubmitBlock(Default::default()), + JReq::GenerateBlocks(_) => JResp::GenerateBlocks(Default::default()), + JReq::GetLastBlockHeader(_) => JResp::GetLastBlockHeader(Default::default()), + JReq::GetBlockHeaderByHash(_) => JResp::GetBlockHeaderByHash(Default::default()), + JReq::GetBlockHeaderByHeight(_) => JResp::GetBlockHeaderByHeight(Default::default()), + JReq::GetBlockHeadersRange(_) => JResp::GetBlockHeadersRange(Default::default()), + JReq::GetBlock(_) => JResp::GetBlock(Default::default()), + JReq::GetConnections(_) => JResp::GetConnections(Default::default()), + JReq::GetInfo(_) => JResp::GetInfo(Default::default()), + JReq::HardForkInfo(_) => JResp::HardForkInfo(Default::default()), + JReq::SetBans(_) => JResp::SetBans(Default::default()), + JReq::GetBans(_) => JResp::GetBans(Default::default()), + JReq::Banned(_) => JResp::Banned(Default::default()), + JReq::FlushTransactionPool(_) => JResp::FlushTransactionPool(Default::default()), + JReq::GetOutputHistogram(_) => JResp::GetOutputHistogram(Default::default()), + JReq::GetCoinbaseTxSum(_) => JResp::GetCoinbaseTxSum(Default::default()), + JReq::GetVersion(_) => JResp::GetVersion(Default::default()), + JReq::GetFeeEstimate(_) => JResp::GetFeeEstimate(Default::default()), + JReq::GetAlternateChains(_) => JResp::GetAlternateChains(Default::default()), + JReq::RelayTx(_) => JResp::RelayTx(Default::default()), + JReq::SyncInfo(_) => JResp::SyncInfo(Default::default()), + JReq::GetTransactionPoolBacklog(_) => JResp::GetTransactionPoolBacklog(Default::default()), + JReq::GetMinerData(_) => JResp::GetMinerData(Default::default()), + JReq::PruneBlockchain(_) => JResp::PruneBlockchain(Default::default()), + JReq::CalcPow(_) => JResp::CalcPow(Default::default()), + JReq::FlushCache(_) => JResp::FlushCache(Default::default()), + JReq::AddAuxPow(_) => JResp::AddAuxPow(Default::default()), + JReq::GetTxIdsLoose(_) => JResp::GetTxIdsLoose(Default::default()), + })), + + // Binary requests. + RpcRequest::Binary(b) => RpcResponse::Binary(match b { + BReq::GetBlocks(_) => BResp::GetBlocks(Default::default()), + BReq::GetBlocksByHeight(_) => BResp::GetBlocksByHeight(Default::default()), + BReq::GetHashes(_) => BResp::GetHashes(Default::default()), + BReq::GetOutputIndexes(_) => BResp::GetOutputIndexes(Default::default()), + BReq::GetOuts(_) => BResp::GetOuts(Default::default()), + BReq::GetTransactionPoolHashes(_) => BResp::GetTransactionPoolHashes(Default::default()), + BReq::GetOutputDistribution(_) => BResp::GetOutputDistribution(Default::default()), + }), + + // JSON (but not JSON-RPC) requests. + RpcRequest::Other(o) => RpcResponse::Other(match o { + OReq::GetHeight(_) => OResp::GetHeight(Default::default()), + OReq::GetTransactions(_) => OResp::GetTransactions(Default::default()), + OReq::GetAltBlocksHashes(_) => OResp::GetAltBlocksHashes(Default::default()), + OReq::IsKeyImageSpent(_) => OResp::IsKeyImageSpent(Default::default()), + OReq::SendRawTransaction(_) => OResp::SendRawTransaction(Default::default()), + OReq::StartMining(_) => OResp::StartMining(Default::default()), + OReq::StopMining(_) => OResp::StopMining(Default::default()), + OReq::MiningStatus(_) => OResp::MiningStatus(Default::default()), + OReq::SaveBc(_) => OResp::SaveBc(Default::default()), + OReq::GetPeerList(_) => OResp::GetPeerList(Default::default()), + OReq::SetLogHashRate(_) => OResp::SetLogHashRate(Default::default()), + OReq::SetLogLevel(_) => OResp::SetLogLevel(Default::default()), + OReq::SetLogCategories(_) => OResp::SetLogCategories(Default::default()), + OReq::SetBootstrapDaemon(_) => OResp::SetBootstrapDaemon(Default::default()), + OReq::GetTransactionPool(_) => OResp::GetTransactionPool(Default::default()), + OReq::GetTransactionPoolStats(_) => OResp::GetTransactionPoolStats(Default::default()), + OReq::StopDaemon(_) => OResp::StopDaemon(Default::default()), + OReq::GetLimit(_) => OResp::GetLimit(Default::default()), + OReq::SetLimit(_) => OResp::SetLimit(Default::default()), + OReq::OutPeers(_) => OResp::OutPeers(Default::default()), + OReq::InPeers(_) => OResp::InPeers(Default::default()), + OReq::GetNetStats(_) => OResp::GetNetStats(Default::default()), + OReq::GetOuts(_) => OResp::GetOuts(Default::default()), + OReq::Update(_) => OResp::Update(Default::default()), + OReq::PopBlocks(_) => OResp::PopBlocks(Default::default()), + OReq::GetTransactionPoolHashes(_) => OResp::GetTransactionPoolHashes(Default::default()), + OReq::GetPublicNodes(_) => OResp::GetPublicNodes(Default::default()), + }) + }; + + let (tx, rx) = channel(); + drop(tx.send(Ok(resp))); + InfallibleOneshotReceiver::from(rx) + } +} diff --git a/binaries/cuprated/src/rpc/request_handler.rs b/binaries/cuprated/src/rpc/request_handler.rs deleted file mode 100644 index 8b1378917..000000000 --- a/binaries/cuprated/src/rpc/request_handler.rs +++ /dev/null @@ -1 +0,0 @@ - From abfc3c503c5bee1264868d382f648ac749ab6186 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 2 Sep 2024 17:37:18 -0400 Subject: [PATCH 05/20] add state, fn signatures --- binaries/cuprated/src/rpc.rs | 3 + binaries/cuprated/src/rpc/bin.rs | 67 ++++++++ binaries/cuprated/src/rpc/handler.rs | 106 ++++-------- binaries/cuprated/src/rpc/json.rs | 248 +++++++++++++++++++++++++++ binaries/cuprated/src/rpc/other.rs | 213 +++++++++++++++++++++++ 5 files changed, 561 insertions(+), 76 deletions(-) create mode 100644 binaries/cuprated/src/rpc/bin.rs create mode 100644 binaries/cuprated/src/rpc/json.rs create mode 100644 binaries/cuprated/src/rpc/other.rs diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 773da8073..efbe72e82 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -2,6 +2,9 @@ //! //! Will contain the code to initiate the RPC and a request handler. +mod bin; mod handler; +mod json; +mod other; pub use handler::CupratedRpcHandler; diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs new file mode 100644 index 000000000..bb99da76e --- /dev/null +++ b/binaries/cuprated/src/rpc/bin.rs @@ -0,0 +1,67 @@ +use cuprate_rpc_types::bin::{ + GetBlocksByHeightRequest, GetBlocksByHeightResponse, GetBlocksRequest, GetBlocksResponse, + GetHashesRequest, GetHashesResponse, GetOutputDistributionRequest, + GetOutputDistributionResponse, GetOutputIndexesRequest, GetOutputIndexesResponse, + GetOutsRequest, GetOutsResponse, GetTransactionPoolHashesRequest, + GetTransactionPoolHashesResponse, +}; + +use crate::rpc::CupratedRpcHandler; + +async fn map_request(state: CupratedRpcHandler, request: BinRpcRequest) -> BinRpcResponse { + use BinRpcRequest as Req; + use BinRpcResponse as Resp; + + match request { + Req::GetBlocks(r) => Resp::GetBlocks(get_blocks(state, r)), + Req::GetBlocksByHeight(r) => Resp::GetBlocksByHeight(get_blocks_by_height(state, r)), + Req::GetHashes(r) => Resp::GetHashes(get_hashes(state, r)), + Req::GetOutputIndexes(r) => Resp::GetOutputIndexes(get_output_indexes(state, r)), + Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)), + Req::GetTransactionPoolHashes(r) => { + Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r)) + } + Req::GetOutputDistribution(r) => { + Resp::GetOutputDistribution(get_output_distribution(state, r)) + } + } +} + +async fn get_blocks(state: CupratedRpcHandler, request: GetBlocksRequest) -> GetBlocksResponse { + todo!() +} + +async fn get_blocks_by_height( + state: CupratedRpcHandler, + request: GetBlocksByHeightRequest, +) -> GetBlocksByHeightResponse { + todo!() +} + +async fn get_hashes(state: CupratedRpcHandler, request: GetHashesRequest) -> GetHashesResponse { + todo!() +} + +async fn get_output_indexes( + state: CupratedRpcHandler, + request: GetOutputIndexesRequest, +) -> GetOutputIndexesResponse { + todo!() +} + +async fn get_outs(state: CupratedRpcHandler, request: GetOutsRequest) -> GetOutsResponse { + todo!() +} + +async fn get_transaction_pool_hashes( + state: CupratedRpcHandler, + request: GetTransactionPoolHashesRequest, +) -> GetTransactionPoolHashesResponse { + todo!() +} +async fn get_output_distribution( + state: CupratedRpcHandler, + request: GetOutputDistributionRequest, +) -> GetOutputDistributionResponse { + todo!() +} diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index fd17a1050..b2506159a 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -7,9 +7,13 @@ use futures::channel::oneshot::channel; use serde::{Deserialize, Serialize}; use tower::Service; +use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle}; use cuprate_helper::asynch::InfallibleOneshotReceiver; use cuprate_json_rpc::Id; use cuprate_rpc_interface::{RpcError, RpcHandler, RpcRequest, RpcResponse}; +use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle}; + +use crate::rpc::{bin, json, other}; //---------------------------------------------------------------------------------------------------- CupratedRpcHandler /// TODO @@ -17,8 +21,23 @@ use cuprate_rpc_interface::{RpcError, RpcHandler, RpcRequest, RpcResponse}; pub struct CupratedRpcHandler { /// Should this RPC server be [restricted](RpcHandler::restricted)? pub restricted: bool, + + /// Read handle to the blockchain database. + pub blockchain_read: BlockchainReadHandle, + /// Write handle to the blockchain database. + pub blockchain_write: BlockchainWriteHandle, + /// Direct handle to the blockchain database. + pub blockchain_db: Arc, + + /// Read handle to the transaction pool database. + pub txpool_read: TxpoolReadHandle, + /// Write handle to the transaction pool database. + pub txpool_write: TxpoolWriteHandle, + /// Direct handle to the transaction pool database. + pub txpool_db: Arc, } +//---------------------------------------------------------------------------------------------------- RpcHandler Impl impl RpcHandler for CupratedRpcHandler { fn restricted(&self) -> bool { self.restricted @@ -42,84 +61,19 @@ impl Service for CupratedRpcHandler { use cuprate_rpc_types::other::OtherRequest as OReq; use cuprate_rpc_types::other::OtherResponse as OResp; - #[rustfmt::skip] - #[allow(clippy::default_trait_access)] - let resp = match req { - // JSON-RPC 2.0 requests. - RpcRequest::JsonRpc(j) => RpcResponse::JsonRpc(cuprate_json_rpc::Response::ok(Id::Null, match j.body { - JReq::GetBlockCount(_) => JResp::GetBlockCount(Default::default()), - JReq::OnGetBlockHash(_) => JResp::OnGetBlockHash(Default::default()), - JReq::SubmitBlock(_) => JResp::SubmitBlock(Default::default()), - JReq::GenerateBlocks(_) => JResp::GenerateBlocks(Default::default()), - JReq::GetLastBlockHeader(_) => JResp::GetLastBlockHeader(Default::default()), - JReq::GetBlockHeaderByHash(_) => JResp::GetBlockHeaderByHash(Default::default()), - JReq::GetBlockHeaderByHeight(_) => JResp::GetBlockHeaderByHeight(Default::default()), - JReq::GetBlockHeadersRange(_) => JResp::GetBlockHeadersRange(Default::default()), - JReq::GetBlock(_) => JResp::GetBlock(Default::default()), - JReq::GetConnections(_) => JResp::GetConnections(Default::default()), - JReq::GetInfo(_) => JResp::GetInfo(Default::default()), - JReq::HardForkInfo(_) => JResp::HardForkInfo(Default::default()), - JReq::SetBans(_) => JResp::SetBans(Default::default()), - JReq::GetBans(_) => JResp::GetBans(Default::default()), - JReq::Banned(_) => JResp::Banned(Default::default()), - JReq::FlushTransactionPool(_) => JResp::FlushTransactionPool(Default::default()), - JReq::GetOutputHistogram(_) => JResp::GetOutputHistogram(Default::default()), - JReq::GetCoinbaseTxSum(_) => JResp::GetCoinbaseTxSum(Default::default()), - JReq::GetVersion(_) => JResp::GetVersion(Default::default()), - JReq::GetFeeEstimate(_) => JResp::GetFeeEstimate(Default::default()), - JReq::GetAlternateChains(_) => JResp::GetAlternateChains(Default::default()), - JReq::RelayTx(_) => JResp::RelayTx(Default::default()), - JReq::SyncInfo(_) => JResp::SyncInfo(Default::default()), - JReq::GetTransactionPoolBacklog(_) => JResp::GetTransactionPoolBacklog(Default::default()), - JReq::GetMinerData(_) => JResp::GetMinerData(Default::default()), - JReq::PruneBlockchain(_) => JResp::PruneBlockchain(Default::default()), - JReq::CalcPow(_) => JResp::CalcPow(Default::default()), - JReq::FlushCache(_) => JResp::FlushCache(Default::default()), - JReq::AddAuxPow(_) => JResp::AddAuxPow(Default::default()), - JReq::GetTxIdsLoose(_) => JResp::GetTxIdsLoose(Default::default()), - })), + // INVARIANT: + // + // We don't need to check for `self.is_restricted()` + // here because `cuprate-rpc-interface` handles that. + // + // We can assume the request coming has the required permissions. - // Binary requests. - RpcRequest::Binary(b) => RpcResponse::Binary(match b { - BReq::GetBlocks(_) => BResp::GetBlocks(Default::default()), - BReq::GetBlocksByHeight(_) => BResp::GetBlocksByHeight(Default::default()), - BReq::GetHashes(_) => BResp::GetHashes(Default::default()), - BReq::GetOutputIndexes(_) => BResp::GetOutputIndexes(Default::default()), - BReq::GetOuts(_) => BResp::GetOuts(Default::default()), - BReq::GetTransactionPoolHashes(_) => BResp::GetTransactionPoolHashes(Default::default()), - BReq::GetOutputDistribution(_) => BResp::GetOutputDistribution(Default::default()), - }), + let state = CupratedRpcHandler::clone(self); - // JSON (but not JSON-RPC) requests. - RpcRequest::Other(o) => RpcResponse::Other(match o { - OReq::GetHeight(_) => OResp::GetHeight(Default::default()), - OReq::GetTransactions(_) => OResp::GetTransactions(Default::default()), - OReq::GetAltBlocksHashes(_) => OResp::GetAltBlocksHashes(Default::default()), - OReq::IsKeyImageSpent(_) => OResp::IsKeyImageSpent(Default::default()), - OReq::SendRawTransaction(_) => OResp::SendRawTransaction(Default::default()), - OReq::StartMining(_) => OResp::StartMining(Default::default()), - OReq::StopMining(_) => OResp::StopMining(Default::default()), - OReq::MiningStatus(_) => OResp::MiningStatus(Default::default()), - OReq::SaveBc(_) => OResp::SaveBc(Default::default()), - OReq::GetPeerList(_) => OResp::GetPeerList(Default::default()), - OReq::SetLogHashRate(_) => OResp::SetLogHashRate(Default::default()), - OReq::SetLogLevel(_) => OResp::SetLogLevel(Default::default()), - OReq::SetLogCategories(_) => OResp::SetLogCategories(Default::default()), - OReq::SetBootstrapDaemon(_) => OResp::SetBootstrapDaemon(Default::default()), - OReq::GetTransactionPool(_) => OResp::GetTransactionPool(Default::default()), - OReq::GetTransactionPoolStats(_) => OResp::GetTransactionPoolStats(Default::default()), - OReq::StopDaemon(_) => OResp::StopDaemon(Default::default()), - OReq::GetLimit(_) => OResp::GetLimit(Default::default()), - OReq::SetLimit(_) => OResp::SetLimit(Default::default()), - OReq::OutPeers(_) => OResp::OutPeers(Default::default()), - OReq::InPeers(_) => OResp::InPeers(Default::default()), - OReq::GetNetStats(_) => OResp::GetNetStats(Default::default()), - OReq::GetOuts(_) => OResp::GetOuts(Default::default()), - OReq::Update(_) => OResp::Update(Default::default()), - OReq::PopBlocks(_) => OResp::PopBlocks(Default::default()), - OReq::GetTransactionPoolHashes(_) => OResp::GetTransactionPoolHashes(Default::default()), - OReq::GetPublicNodes(_) => OResp::GetPublicNodes(Default::default()), - }) + let resp = match req { + RpcRequest::JsonRpc(r) => json::map_request(r), // JSON-RPC 2.0 requests. + RpcRequest::Binary(r) => bin::map_request(r), // Binary requests. + RpcRequest::Other(o) => other::map_request(r), // JSON (but not JSON-RPC) requests. }; let (tx, rx) = channel(); diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs new file mode 100644 index 000000000..3286100f8 --- /dev/null +++ b/binaries/cuprated/src/rpc/json.rs @@ -0,0 +1,248 @@ +use std::sync::Arc; + +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::CupratedRpcHandler; + +async fn map_request(state: CupratedRpcHandler, request: JsonRpcRequest) -> JsonRpcResponse { + use JsonRpcRequest as Req; + use JsonRpcResponse as Resp; + + match request { + Req::GetBlockCount(r) => Resp::GetBlockCount(get_block_count(state, r)), + Req::OnGetBlockHash(r) => Resp::OnGetBlockHash(on_get_block_hash(state, r)), + Req::SubmitBlock(r) => Resp::SubmitBlock(submit_block(state, r)), + Req::GenerateBlocks(r) => Resp::GenerateBlocks(generate_blocks(state, r)), + Req::GetLastBlockHeader(r) => Resp::GetLastBlockHeader(get_last_block_header(state, r)), + Req::GetBlockHeaderByHash(r) => { + Resp::GetBlockHeaderByHash(get_block_header_by_hash(state, r)) + } + Req::GetBlockHeaderByHeight(r) => { + Resp::GetBlockHeaderByHeight(get_block_header_by_height(state, r)) + } + Req::GetBlockHeadersRange(r) => { + Resp::GetBlockHeadersRange(get_block_headers_range(state, r)) + } + Req::GetBlock(r) => Resp::GetBlock(get_block(state, r)), + Req::GetConnections(r) => Resp::GetConnections(get_connections(state, r)), + Req::GetInfo(r) => Resp::GetInfo(get_info(state, r)), + Req::HardForkInfo(r) => Resp::HardForkInfo(hard_fork_info(state, r)), + Req::SetBans(r) => Resp::SetBans(set_bans(state, r)), + Req::GetBans(r) => Resp::GetBans(get_bans(state, r)), + Req::Banned(r) => Resp::Banned(banned(state, r)), + Req::FlushTransactionPool(r) => { + Resp::FlushTransactionPool(flush_transaction_pool(state, r)) + } + Req::GetOutputHistogram(r) => Resp::GetOutputHistogram(get_output_histogram(state, r)), + Req::GetCoinbaseTxSum(r) => Resp::GetCoinbaseTxSum(get_coinbase_tx_sum(state, r)), + Req::GetVersion(r) => Resp::GetVersion(get_version(state, r)), + Req::GetFeeEstimate(r) => Resp::GetFeeEstimate(get_fee_estimate(state, r)), + Req::GetAlternateChains(r) => Resp::GetAlternateChains(get_alternate_chains(state, r)), + Req::RelayTx(r) => Resp::RelayTx(relay_tx(state, r)), + Req::SyncInfo(r) => Resp::SyncInfo(sync_info(state, r)), + Req::GetTransactionPoolBacklog(r) => { + Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r)) + } + Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r)), + Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r)), + Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r)), + Req::FlushCache(r) => Resp::FlushCache(flush_cache(state, r)), + Req::AddAuxPow(r) => Resp::AddAuxPow(add_aux_pow(state, r)), + Req::GetTxIdsLoose(r) => Resp::GetTxIdsLoose(get_tx_ids_loose(state, r)), + } +} + +async fn get_block_count( + state: CupratedRpcHandler, + request: GetBlockCountRequest, +) -> GetBlockCountResponse { + todo!() +} + +async fn on_get_block_hash( + state: CupratedRpcHandler, + request: OnGetBlockHashRequest, +) -> OnGetBlockHashResponse { + todo!() +} + +async fn submit_block( + state: CupratedRpcHandler, + request: SubmitBlockRequest, +) -> SubmitBlockResponse { + todo!() +} + +async fn generate_blocks( + state: CupratedRpcHandler, + request: GenerateBlocksRequest, +) -> GenerateBlocksResponse { + todo!() +} + +async fn get_last_block_header( + state: CupratedRpcHandler, + request: GetLastBlockHeaderRequest, +) -> GetLastBlockHeaderResponse { + todo!() +} + +async fn get_block_header_by_hash( + state: CupratedRpcHandler, + request: GetBlockHeaderByHashRequest, +) -> GetBlockHeaderByHashResponse { + todo!() +} + +async fn get_block_header_by_height( + state: CupratedRpcHandler, + request: GetBlockHeaderByHeightRequest, +) -> GetBlockHeaderByHeightResponse { + todo!() +} + +async fn get_block_headers_range( + state: CupratedRpcHandler, + request: GetBlockHeadersRangeRequest, +) -> GetBlockHeadersRangeResponse { + todo!() +} + +async fn get_block(state: CupratedRpcHandler, request: GetBlockRequest) -> GetBlockResponse { + todo!() +} + +async fn get_connections( + state: CupratedRpcHandler, + request: GetConnectionsRequest, +) -> GetConnectionsResponse { + todo!() +} + +async fn get_info(state: CupratedRpcHandler, request: GetInfoRequest) -> GetInfoResponse { + todo!() +} + +async fn hard_fork_info( + state: CupratedRpcHandler, + request: HardForkInfoRequest, +) -> HardForkInfoResponse { + todo!() +} + +async fn set_bans(state: CupratedRpcHandler, request: SetBansRequest) -> SetBansResponse { + todo!() +} + +async fn get_bans(state: CupratedRpcHandler, request: GetBansRequest) -> GetBansResponse { + todo!() +} + +async fn banned(state: CupratedRpcHandler, request: BannedRequest) -> BannedResponse { + todo!() +} + +async fn flush_transaction_pool( + state: CupratedRpcHandler, + request: FlushTransactionPoolRequest, +) -> FlushTransactionPoolResponse { + todo!() +} + +async fn get_output_histogram( + state: CupratedRpcHandler, + request: GetOutputHistogramRequest, +) -> GetOutputHistogramResponse { + todo!() +} + +async fn get_coinbase_tx_sum( + state: CupratedRpcHandler, + request: GetCoinbaseTxSumRequest, +) -> GetCoinbaseTxSumResponse { + todo!() +} + +async fn get_version(state: CupratedRpcHandler, request: GetVersionRequest) -> GetVersionResponse { + todo!() +} + +async fn get_fee_estimate( + state: CupratedRpcHandler, + request: GetFeeEstimateRequest, +) -> GetFeeEstimateResponse { + todo!() +} + +async fn get_alternate_chains( + state: CupratedRpcHandler, + request: GetAlternateChainsRequest, +) -> GetAlternateChainsResponse { + todo!() +} + +async fn relay_tx(state: CupratedRpcHandler, request: RelayTxRequest) -> RelayTxResponse { + todo!() +} + +async fn sync_info(state: CupratedRpcHandler, request: SyncInfoRequest) -> SyncInfoResponse { + todo!() +} + +async fn get_transaction_pool_backlog( + state: CupratedRpcHandler, + request: GetTransactionPoolBacklogRequest, +) -> GetTransactionPoolBacklogResponse { + todo!() +} + +async fn get_miner_data( + state: CupratedRpcHandler, + request: GetMinerDataRequest, +) -> GetMinerDataResponse { + todo!() +} + +async fn prune_blockchain( + state: CupratedRpcHandler, + request: PruneBlockchainRequest, +) -> PruneBlockchainResponse { + todo!() +} + +async fn calc_pow(state: CupratedRpcHandler, request: CalcPowRequest) -> CalcPowResponse { + todo!() +} + +async fn flush_cache(state: CupratedRpcHandler, request: FlushCacheRequest) -> FlushCacheResponse { + todo!() +} + +async fn add_aux_pow(state: CupratedRpcHandler, request: AddAuxPowRequest) -> AddAuxPowResponse { + todo!() +} + +async fn get_tx_ids_loose( + state: CupratedRpcHandler, + request: GetTxIdsLooseRequest, +) -> GetTxIdsLooseResponse { + todo!() +} diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs new file mode 100644 index 000000000..f1bb8590b --- /dev/null +++ b/binaries/cuprated/src/rpc/other.rs @@ -0,0 +1,213 @@ +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, 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::CupratedRpcHandler; + +async fn map_request(state: CupratedRpcHandler, request: OtherRpcRequest) -> OtherRpcResponse { + use OtherRpcRequest as Req; + use OtherRpcResponse as Resp; + + match request { + Req::GetHeight(r) => Resp::GetHeight(get_height(state, r)), + Req::GetTransactions(r) => Resp::GetTransactions(get_transactions(state, r)), + Req::GetAltBlocksHashes(r) => Resp::GetAltBlocksHashes(get_alt_blocks_hashes(state, r)), + Req::IsKeyImageSpent(r) => Resp::IsKeyImageSpent(is_key_image_spent(state, r)), + Req::SendRawTransaction(r) => Resp::SendRawTransaction(send_raw_transaction(state, r)), + Req::StartMining(r) => Resp::StartMining(start_mining(state, r)), + Req::StopMining(r) => Resp::StopMining(stop_mining(state, r)), + Req::MiningStatus(r) => Resp::MiningStatus(mining_status(state, r)), + Req::SaveBc(r) => Resp::SaveBc(save_bc(state, r)), + Req::GetPeerList(r) => Resp::GetPeerList(get_peer_list(state, r)), + Req::SetLogHashRate(r) => Resp::SetLogHashRate(set_log_hash_rate(state, r)), + Req::SetLogLevel(r) => Resp::SetLogLevel(set_log_level(state, r)), + Req::SetLogCategories(r) => Resp::SetLogCategories(set_log_categories(state, r)), + Req::SetBootstrapDaemon(r) => Resp::SetBootstrapDaemon(set_bootstrap_daemon(state, r)), + Req::GetTransactionPool(r) => Resp::GetTransactionPool(get_transaction_pool(state, r)), + Req::GetTransactionPoolStats(r) => { + Resp::GetTransactionPoolStats(get_transaction_pool_stats(state, r)) + } + Req::StopDaemon(r) => Resp::StopDaemon(stop_daemon(state, r)), + Req::GetLimit(r) => Resp::GetLimit(get_limit(state, r)), + Req::SetLimit(r) => Resp::SetLimit(set_limit(state, r)), + Req::OutPeers(r) => Resp::OutPeers(out_peers(state, r)), + Req::InPeers(r) => Resp::InPeers(in_peers(state, r)), + Req::GetNetStats(r) => Resp::GetNetStats(get_net_stats(state, r)), + Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)), + Req::Update(r) => Resp::Update(update(state, r)), + Req::PopBlocks(r) => Resp::PopBlocks(pop_blocks(state, r)), + Req::GetTransactionPoolHashes(r) => { + Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r)) + } + Req::GetPublicNodes(r) => Resp::GetPublicNodes(get_public_nodes(state, r)), + } +} + +async fn get_height(state: CupratedRpcHandler, request: GetHeightRequest) -> GetHeightResponse { + todo!() +} + +async fn get_transactions( + state: CupratedRpcHandler, + request: GetTransactionsRequest, +) -> GetTransactionsResponse { + todo!() +} + +async fn get_alt_blocks_hashes( + state: CupratedRpcHandler, + request: GetAltBlocksHashesRequest, +) -> GetAltBlocksHashesResponse { + todo!() +} + +async fn is_key_image_spent( + state: CupratedRpcHandler, + request: IsKeyImageSpentRequest, +) -> IsKeyImageSpentResponse { + todo!() +} + +async fn send_raw_transaction( + state: CupratedRpcHandler, + request: SendRawTransactionRequest, +) -> SendRawTransactionResponse { + todo!() +} + +async fn start_mining( + state: CupratedRpcHandler, + request: StartMiningRequest, +) -> StartMiningResponse { + todo!() +} + +async fn stop_mining(state: CupratedRpcHandler, request: StopMiningRequest) -> StopMiningResponse { + todo!() +} + +async fn mining_status( + state: CupratedRpcHandler, + request: MiningStatusRequest, +) -> MiningStatusResponse { + todo!() +} + +async fn save_bc(state: CupratedRpcHandler, request: SaveBcRequest) -> SaveBcResponse { + todo!() +} + +async fn get_peer_list( + state: CupratedRpcHandler, + request: GetPeerListRequest, +) -> GetPeerListResponse { + todo!() +} + +async fn set_log_hash_rate( + state: CupratedRpcHandler, + request: SetLogHashRateRequest, +) -> SetLogHashRateResponse { + todo!() +} + +async fn set_log_level( + state: CupratedRpcHandler, + request: SetLogLevelRequest, +) -> SetLogLevelResponse { + todo!() +} + +async fn set_log_categories( + state: CupratedRpcHandler, + request: SetLogCategoriesRequest, +) -> SetLogCategoriesResponse { + todo!() +} + +async fn set_bootstrap_daemon( + state: CupratedRpcHandler, + request: SetBootstrapDaemonRequest, +) -> SetBootstrapDaemonResponse { + todo!() +} + +async fn get_transaction_pool( + state: CupratedRpcHandler, + request: GetTransactionPoolRequest, +) -> GetTransactionPoolResponse { + todo!() +} + +async fn get_transaction_pool_stats( + state: CupratedRpcHandler, + request: GetTransactionPoolStatsRequest, +) -> GetTransactionPoolStatsResponse { + todo!() +} + +async fn stop_daemon(state: CupratedRpcHandler, request: StopDaemonRequest) -> StopDaemonResponse { + todo!() +} + +async fn get_limit(state: CupratedRpcHandler, request: GetLimitRequest) -> GetLimitResponse { + todo!() +} + +async fn set_limit(state: CupratedRpcHandler, request: SetLimitRequest) -> SetLimitResponse { + todo!() +} + +async fn out_peers(state: CupratedRpcHandler, request: OutPeersRequest) -> OutPeersResponse { + todo!() +} + +async fn in_peers(state: CupratedRpcHandler, request: InPeersRequest) -> InPeersResponse { + todo!() +} + +async fn get_net_stats( + state: CupratedRpcHandler, + request: GetNetStatsRequest, +) -> GetNetStatsResponse { + todo!() +} + +async fn get_outs(state: CupratedRpcHandler, request: GetOutsRequest) -> GetOutsResponse { + todo!() +} + +async fn update(state: CupratedRpcHandler, request: UpdateRequest) -> UpdateResponse { + todo!() +} + +async fn pop_blocks(state: CupratedRpcHandler, request: PopBlocksRequest) -> PopBlocksResponse { + todo!() +} + +async fn get_transaction_pool_hashes( + state: CupratedRpcHandler, + request: GetTransactionPoolHashesRequest, +) -> GetTransactionPoolHashesResponse { + todo!() +} + +async fn get_public_nodes( + state: CupratedRpcHandler, + request: GetPublicNodesRequest, +) -> GetPublicNodesResponse { + todo!() +} From f89e29eebabb40ce2404aea84beb6dee3220ae84 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 2 Sep 2024 17:47:23 -0400 Subject: [PATCH 06/20] fixes --- binaries/cuprated/src/rpc/bin.rs | 3 ++- binaries/cuprated/src/rpc/handler.rs | 26 +++++++++----------------- binaries/cuprated/src/rpc/json.rs | 5 ++++- binaries/cuprated/src/rpc/other.rs | 5 ++++- 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs index bb99da76e..547848f82 100644 --- a/binaries/cuprated/src/rpc/bin.rs +++ b/binaries/cuprated/src/rpc/bin.rs @@ -8,7 +8,7 @@ use cuprate_rpc_types::bin::{ use crate::rpc::CupratedRpcHandler; -async fn map_request(state: CupratedRpcHandler, request: BinRpcRequest) -> BinRpcResponse { +pub(super) async fn map_request(state: CupratedRpcHandler, request: BinRpcRequest) -> BinRpcResponse { use BinRpcRequest as Req; use BinRpcResponse as Resp; @@ -59,6 +59,7 @@ async fn get_transaction_pool_hashes( ) -> GetTransactionPoolHashesResponse { todo!() } + async fn get_output_distribution( state: CupratedRpcHandler, request: GetOutputDistributionRequest, diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index b2506159a..760c3dbee 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -53,27 +53,19 @@ impl Service for CupratedRpcHandler { Poll::Ready(Ok(())) } + /// INVARIANT: + /// + /// We don't need to check for `self.is_restricted()` + /// here because `cuprate-rpc-interface` handles that. + /// + /// We can assume the request coming has the required permissions. fn call(&mut self, req: RpcRequest) -> Self::Future { - use cuprate_rpc_types::bin::BinRequest as BReq; - use cuprate_rpc_types::bin::BinResponse as BResp; - use cuprate_rpc_types::json::JsonRpcRequest as JReq; - use cuprate_rpc_types::json::JsonRpcResponse as JResp; - use cuprate_rpc_types::other::OtherRequest as OReq; - use cuprate_rpc_types::other::OtherResponse as OResp; - - // INVARIANT: - // - // We don't need to check for `self.is_restricted()` - // here because `cuprate-rpc-interface` handles that. - // - // We can assume the request coming has the required permissions. - let state = CupratedRpcHandler::clone(self); let resp = match req { - RpcRequest::JsonRpc(r) => json::map_request(r), // JSON-RPC 2.0 requests. - RpcRequest::Binary(r) => bin::map_request(r), // Binary requests. - RpcRequest::Other(o) => other::map_request(r), // JSON (but not JSON-RPC) requests. + RpcRequest::JsonRpc(r) => json::map_request(state, r), // JSON-RPC 2.0 requests. + RpcRequest::Binary(r) => bin::map_request(state, r), // Binary requests. + RpcRequest::Other(o) => other::map_request(state, r), // JSON (but not JSON-RPC) requests. }; let (tx, rx) = channel(); diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 3286100f8..14cbd2566 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -22,7 +22,10 @@ use cuprate_rpc_types::json::{ use crate::rpc::CupratedRpcHandler; -async fn map_request(state: CupratedRpcHandler, request: JsonRpcRequest) -> JsonRpcResponse { +pub(super) async fn map_request( + state: CupratedRpcHandler, + request: JsonRpcRequest, +) -> JsonRpcResponse { use JsonRpcRequest as Req; use JsonRpcResponse as Resp; diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index f1bb8590b..c570dfae6 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -17,7 +17,10 @@ use cuprate_rpc_types::other::{ use crate::rpc::CupratedRpcHandler; -async fn map_request(state: CupratedRpcHandler, request: OtherRpcRequest) -> OtherRpcResponse { +pub(super) async fn map_request( + state: CupratedRpcHandler, + request: OtherRpcRequest, +) -> OtherRpcResponse { use OtherRpcRequest as Req; use OtherRpcResponse as Resp; From 5f377717295173cf8578a5fad562af49b36482ee Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 2 Sep 2024 18:08:52 -0400 Subject: [PATCH 07/20] error signatures --- binaries/cuprated/src/rpc.rs | 2 + binaries/cuprated/src/rpc/bin.rs | 73 +++++---- binaries/cuprated/src/rpc/handler.rs | 35 ++--- binaries/cuprated/src/rpc/json.rs | 197 ++++++++++++++---------- binaries/cuprated/src/rpc/other.rs | 200 ++++++++++++++----------- rpc/interface/src/route/json_rpc.rs | 4 +- rpc/interface/src/rpc_handler_dummy.rs | 4 +- rpc/interface/src/rpc_request.rs | 2 +- rpc/interface/src/rpc_response.rs | 2 +- 9 files changed, 296 insertions(+), 223 deletions(-) diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index efbe72e82..55051e1ae 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -2,6 +2,8 @@ //! //! Will contain the code to initiate the RPC and a request handler. +#![allow(clippy::needless_pass_by_value)] // TODO: remove after impl. + mod bin; mod handler; mod json; diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs index 547848f82..a03808d71 100644 --- a/binaries/cuprated/src/rpc/bin.rs +++ b/binaries/cuprated/src/rpc/bin.rs @@ -1,68 +1,83 @@ -use cuprate_rpc_types::bin::{ - GetBlocksByHeightRequest, GetBlocksByHeightResponse, GetBlocksRequest, GetBlocksResponse, - GetHashesRequest, GetHashesResponse, GetOutputDistributionRequest, - GetOutputDistributionResponse, GetOutputIndexesRequest, GetOutputIndexesResponse, - GetOutsRequest, GetOutsResponse, GetTransactionPoolHashesRequest, - GetTransactionPoolHashesResponse, +use cuprate_rpc_interface::{RpcError, RpcResponse}; +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::CupratedRpcHandler; -pub(super) async fn map_request(state: CupratedRpcHandler, request: BinRpcRequest) -> BinRpcResponse { - use BinRpcRequest as Req; - use BinRpcResponse as Resp; +pub(super) fn map_request( + state: CupratedRpcHandler, + request: BinRequest, +) -> Result { + use BinRequest as Req; + use BinResponse as Resp; - match request { - Req::GetBlocks(r) => Resp::GetBlocks(get_blocks(state, r)), - Req::GetBlocksByHeight(r) => Resp::GetBlocksByHeight(get_blocks_by_height(state, r)), - Req::GetHashes(r) => Resp::GetHashes(get_hashes(state, r)), - Req::GetOutputIndexes(r) => Resp::GetOutputIndexes(get_output_indexes(state, r)), - Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)), + Ok(match request { + Req::GetBlocks(r) => Resp::GetBlocks(get_blocks(state, r)?), + Req::GetBlocksByHeight(r) => Resp::GetBlocksByHeight(get_blocks_by_height(state, r)?), + Req::GetHashes(r) => Resp::GetHashes(get_hashes(state, r)?), + Req::GetOutputIndexes(r) => Resp::GetOutputIndexes(get_output_indexes(state, r)?), + Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)?), Req::GetTransactionPoolHashes(r) => { - Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r)) + Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r)?) } Req::GetOutputDistribution(r) => { - Resp::GetOutputDistribution(get_output_distribution(state, r)) + Resp::GetOutputDistribution(get_output_distribution(state, r)?) } - } + }) } -async fn get_blocks(state: CupratedRpcHandler, request: GetBlocksRequest) -> GetBlocksResponse { +fn get_blocks( + state: CupratedRpcHandler, + request: GetBlocksRequest, +) -> Result { todo!() } -async fn get_blocks_by_height( +fn get_blocks_by_height( state: CupratedRpcHandler, request: GetBlocksByHeightRequest, -) -> GetBlocksByHeightResponse { +) -> Result { todo!() } -async fn get_hashes(state: CupratedRpcHandler, request: GetHashesRequest) -> GetHashesResponse { +fn get_hashes( + state: CupratedRpcHandler, + request: GetHashesRequest, +) -> Result { todo!() } -async fn get_output_indexes( +fn get_output_indexes( state: CupratedRpcHandler, request: GetOutputIndexesRequest, -) -> GetOutputIndexesResponse { +) -> Result { todo!() } -async fn get_outs(state: CupratedRpcHandler, request: GetOutsRequest) -> GetOutsResponse { +fn get_outs( + state: CupratedRpcHandler, + request: GetOutsRequest, +) -> Result { todo!() } -async fn get_transaction_pool_hashes( +fn get_transaction_pool_hashes( state: CupratedRpcHandler, request: GetTransactionPoolHashesRequest, -) -> GetTransactionPoolHashesResponse { +) -> Result { todo!() } -async fn get_output_distribution( +fn get_output_distribution( state: CupratedRpcHandler, request: GetOutputDistributionRequest, -) -> GetOutputDistributionResponse { +) -> Result { todo!() } diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 760c3dbee..86897f134 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -7,34 +7,26 @@ use futures::channel::oneshot::channel; use serde::{Deserialize, Serialize}; use tower::Service; -use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle}; +use cuprate_blockchain::service::BlockchainReadHandle; use cuprate_helper::asynch::InfallibleOneshotReceiver; use cuprate_json_rpc::Id; use cuprate_rpc_interface::{RpcError, RpcHandler, RpcRequest, RpcResponse}; -use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle}; +use cuprate_txpool::service::TxpoolReadHandle; use crate::rpc::{bin, json, other}; //---------------------------------------------------------------------------------------------------- CupratedRpcHandler /// TODO -#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)] +#[derive(Clone)] pub struct CupratedRpcHandler { /// Should this RPC server be [restricted](RpcHandler::restricted)? pub restricted: bool, /// Read handle to the blockchain database. - pub blockchain_read: BlockchainReadHandle, - /// Write handle to the blockchain database. - pub blockchain_write: BlockchainWriteHandle, - /// Direct handle to the blockchain database. - pub blockchain_db: Arc, + pub blockchain: BlockchainReadHandle, /// Read handle to the transaction pool database. - pub txpool_read: TxpoolReadHandle, - /// Write handle to the transaction pool database. - pub txpool_write: TxpoolWriteHandle, - /// Direct handle to the transaction pool database. - pub txpool_db: Arc, + pub txpool: TxpoolReadHandle, } //---------------------------------------------------------------------------------------------------- RpcHandler Impl @@ -60,16 +52,19 @@ impl Service for CupratedRpcHandler { /// /// We can assume the request coming has the required permissions. fn call(&mut self, req: RpcRequest) -> Self::Future { - let state = CupratedRpcHandler::clone(self); + let state = Self::clone(self); let resp = match req { - RpcRequest::JsonRpc(r) => json::map_request(state, r), // JSON-RPC 2.0 requests. - RpcRequest::Binary(r) => bin::map_request(state, r), // Binary requests. - RpcRequest::Other(o) => other::map_request(state, r), // JSON (but not JSON-RPC) requests. + RpcRequest::JsonRpc(r) => { + RpcResponse::JsonRpc(json::map_request(state, r).expect("TODO")) + } // JSON-RPC 2.0 requests. + RpcRequest::Binary(r) => RpcResponse::Binary(bin::map_request(state, r).expect("TODO")), // Binary requests. + RpcRequest::Other(r) => RpcResponse::Other(other::map_request(state, r).expect("TODO")), // JSON (but not JSON-RPC) requests. }; - let (tx, rx) = channel(); - drop(tx.send(Ok(resp))); - InfallibleOneshotReceiver::from(rx) + todo!() + // let (tx, rx) = channel(); + // drop(tx.send(Ok(resp))); + // InfallibleOneshotReceiver::from(rx) } } diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 14cbd2566..70a9e497b 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use cuprate_rpc_interface::{RpcError, RpcResponse}; use cuprate_rpc_types::json::{ AddAuxPowRequest, AddAuxPowResponse, BannedRequest, BannedResponse, CalcPowRequest, CalcPowResponse, FlushCacheRequest, FlushCacheResponse, FlushTransactionPoolRequest, @@ -22,230 +23,260 @@ use cuprate_rpc_types::json::{ use crate::rpc::CupratedRpcHandler; -pub(super) async fn map_request( +pub(super) fn map_request( state: CupratedRpcHandler, request: JsonRpcRequest, -) -> JsonRpcResponse { +) -> Result { use JsonRpcRequest as Req; use JsonRpcResponse as Resp; - match request { - Req::GetBlockCount(r) => Resp::GetBlockCount(get_block_count(state, r)), - Req::OnGetBlockHash(r) => Resp::OnGetBlockHash(on_get_block_hash(state, r)), - Req::SubmitBlock(r) => Resp::SubmitBlock(submit_block(state, r)), - Req::GenerateBlocks(r) => Resp::GenerateBlocks(generate_blocks(state, r)), - Req::GetLastBlockHeader(r) => Resp::GetLastBlockHeader(get_last_block_header(state, r)), + Ok(match request { + Req::GetBlockCount(r) => Resp::GetBlockCount(get_block_count(state, r)?), + Req::OnGetBlockHash(r) => Resp::OnGetBlockHash(on_get_block_hash(state, r)?), + Req::SubmitBlock(r) => Resp::SubmitBlock(submit_block(state, r)?), + Req::GenerateBlocks(r) => Resp::GenerateBlocks(generate_blocks(state, r)?), + Req::GetLastBlockHeader(r) => Resp::GetLastBlockHeader(get_last_block_header(state, r)?), Req::GetBlockHeaderByHash(r) => { - Resp::GetBlockHeaderByHash(get_block_header_by_hash(state, r)) + Resp::GetBlockHeaderByHash(get_block_header_by_hash(state, r)?) } Req::GetBlockHeaderByHeight(r) => { - Resp::GetBlockHeaderByHeight(get_block_header_by_height(state, r)) + Resp::GetBlockHeaderByHeight(get_block_header_by_height(state, r)?) } Req::GetBlockHeadersRange(r) => { - Resp::GetBlockHeadersRange(get_block_headers_range(state, r)) + Resp::GetBlockHeadersRange(get_block_headers_range(state, r)?) } - Req::GetBlock(r) => Resp::GetBlock(get_block(state, r)), - Req::GetConnections(r) => Resp::GetConnections(get_connections(state, r)), - Req::GetInfo(r) => Resp::GetInfo(get_info(state, r)), - Req::HardForkInfo(r) => Resp::HardForkInfo(hard_fork_info(state, r)), - Req::SetBans(r) => Resp::SetBans(set_bans(state, r)), - Req::GetBans(r) => Resp::GetBans(get_bans(state, r)), - Req::Banned(r) => Resp::Banned(banned(state, r)), + Req::GetBlock(r) => Resp::GetBlock(get_block(state, r)?), + Req::GetConnections(r) => Resp::GetConnections(get_connections(state, r)?), + Req::GetInfo(r) => Resp::GetInfo(get_info(state, r)?), + Req::HardForkInfo(r) => Resp::HardForkInfo(hard_fork_info(state, r)?), + Req::SetBans(r) => Resp::SetBans(set_bans(state, r)?), + Req::GetBans(r) => Resp::GetBans(get_bans(state, r)?), + Req::Banned(r) => Resp::Banned(banned(state, r)?), Req::FlushTransactionPool(r) => { - Resp::FlushTransactionPool(flush_transaction_pool(state, r)) + Resp::FlushTransactionPool(flush_transaction_pool(state, r)?) } - Req::GetOutputHistogram(r) => Resp::GetOutputHistogram(get_output_histogram(state, r)), - Req::GetCoinbaseTxSum(r) => Resp::GetCoinbaseTxSum(get_coinbase_tx_sum(state, r)), - Req::GetVersion(r) => Resp::GetVersion(get_version(state, r)), - Req::GetFeeEstimate(r) => Resp::GetFeeEstimate(get_fee_estimate(state, r)), - Req::GetAlternateChains(r) => Resp::GetAlternateChains(get_alternate_chains(state, r)), - Req::RelayTx(r) => Resp::RelayTx(relay_tx(state, r)), - Req::SyncInfo(r) => Resp::SyncInfo(sync_info(state, r)), + Req::GetOutputHistogram(r) => Resp::GetOutputHistogram(get_output_histogram(state, r)?), + Req::GetCoinbaseTxSum(r) => Resp::GetCoinbaseTxSum(get_coinbase_tx_sum(state, r)?), + Req::GetVersion(r) => Resp::GetVersion(get_version(state, r)?), + Req::GetFeeEstimate(r) => Resp::GetFeeEstimate(get_fee_estimate(state, r)?), + Req::GetAlternateChains(r) => Resp::GetAlternateChains(get_alternate_chains(state, r)?), + Req::RelayTx(r) => Resp::RelayTx(relay_tx(state, r)?), + Req::SyncInfo(r) => Resp::SyncInfo(sync_info(state, r)?), Req::GetTransactionPoolBacklog(r) => { - Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r)) + Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r)?) } - Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r)), - Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r)), - Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r)), - Req::FlushCache(r) => Resp::FlushCache(flush_cache(state, r)), - Req::AddAuxPow(r) => Resp::AddAuxPow(add_aux_pow(state, r)), - Req::GetTxIdsLoose(r) => Resp::GetTxIdsLoose(get_tx_ids_loose(state, r)), - } + Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r)?), + Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r)?), + Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r)?), + Req::FlushCache(r) => Resp::FlushCache(flush_cache(state, r)?), + Req::AddAuxPow(r) => Resp::AddAuxPow(add_aux_pow(state, r)?), + Req::GetTxIdsLoose(r) => Resp::GetTxIdsLoose(get_tx_ids_loose(state, r)?), + }) } -async fn get_block_count( +fn get_block_count( state: CupratedRpcHandler, request: GetBlockCountRequest, -) -> GetBlockCountResponse { +) -> Result { todo!() } -async fn on_get_block_hash( +fn on_get_block_hash( state: CupratedRpcHandler, request: OnGetBlockHashRequest, -) -> OnGetBlockHashResponse { +) -> Result { todo!() } -async fn submit_block( +fn submit_block( state: CupratedRpcHandler, request: SubmitBlockRequest, -) -> SubmitBlockResponse { +) -> Result { todo!() } -async fn generate_blocks( +fn generate_blocks( state: CupratedRpcHandler, request: GenerateBlocksRequest, -) -> GenerateBlocksResponse { +) -> Result { todo!() } -async fn get_last_block_header( +fn get_last_block_header( state: CupratedRpcHandler, request: GetLastBlockHeaderRequest, -) -> GetLastBlockHeaderResponse { +) -> Result { todo!() } -async fn get_block_header_by_hash( +fn get_block_header_by_hash( state: CupratedRpcHandler, request: GetBlockHeaderByHashRequest, -) -> GetBlockHeaderByHashResponse { +) -> Result { todo!() } -async fn get_block_header_by_height( +fn get_block_header_by_height( state: CupratedRpcHandler, request: GetBlockHeaderByHeightRequest, -) -> GetBlockHeaderByHeightResponse { +) -> Result { todo!() } -async fn get_block_headers_range( +fn get_block_headers_range( state: CupratedRpcHandler, request: GetBlockHeadersRangeRequest, -) -> GetBlockHeadersRangeResponse { +) -> Result { todo!() } -async fn get_block(state: CupratedRpcHandler, request: GetBlockRequest) -> GetBlockResponse { +fn get_block( + state: CupratedRpcHandler, + request: GetBlockRequest, +) -> Result { todo!() } -async fn get_connections( +fn get_connections( state: CupratedRpcHandler, request: GetConnectionsRequest, -) -> GetConnectionsResponse { +) -> Result { todo!() } -async fn get_info(state: CupratedRpcHandler, request: GetInfoRequest) -> GetInfoResponse { +fn get_info( + state: CupratedRpcHandler, + request: GetInfoRequest, +) -> Result { todo!() } -async fn hard_fork_info( +fn hard_fork_info( state: CupratedRpcHandler, request: HardForkInfoRequest, -) -> HardForkInfoResponse { +) -> Result { todo!() } -async fn set_bans(state: CupratedRpcHandler, request: SetBansRequest) -> SetBansResponse { +fn set_bans( + state: CupratedRpcHandler, + request: SetBansRequest, +) -> Result { todo!() } -async fn get_bans(state: CupratedRpcHandler, request: GetBansRequest) -> GetBansResponse { +fn get_bans( + state: CupratedRpcHandler, + request: GetBansRequest, +) -> Result { todo!() } -async fn banned(state: CupratedRpcHandler, request: BannedRequest) -> BannedResponse { +fn banned(state: CupratedRpcHandler, request: BannedRequest) -> Result { todo!() } -async fn flush_transaction_pool( +fn flush_transaction_pool( state: CupratedRpcHandler, request: FlushTransactionPoolRequest, -) -> FlushTransactionPoolResponse { +) -> Result { todo!() } -async fn get_output_histogram( +fn get_output_histogram( state: CupratedRpcHandler, request: GetOutputHistogramRequest, -) -> GetOutputHistogramResponse { +) -> Result { todo!() } -async fn get_coinbase_tx_sum( +fn get_coinbase_tx_sum( state: CupratedRpcHandler, request: GetCoinbaseTxSumRequest, -) -> GetCoinbaseTxSumResponse { +) -> Result { todo!() } -async fn get_version(state: CupratedRpcHandler, request: GetVersionRequest) -> GetVersionResponse { +fn get_version( + state: CupratedRpcHandler, + request: GetVersionRequest, +) -> Result { todo!() } -async fn get_fee_estimate( +fn get_fee_estimate( state: CupratedRpcHandler, request: GetFeeEstimateRequest, -) -> GetFeeEstimateResponse { +) -> Result { todo!() } -async fn get_alternate_chains( +fn get_alternate_chains( state: CupratedRpcHandler, request: GetAlternateChainsRequest, -) -> GetAlternateChainsResponse { +) -> Result { todo!() } -async fn relay_tx(state: CupratedRpcHandler, request: RelayTxRequest) -> RelayTxResponse { +fn relay_tx( + state: CupratedRpcHandler, + request: RelayTxRequest, +) -> Result { todo!() } -async fn sync_info(state: CupratedRpcHandler, request: SyncInfoRequest) -> SyncInfoResponse { +fn sync_info( + state: CupratedRpcHandler, + request: SyncInfoRequest, +) -> Result { todo!() } -async fn get_transaction_pool_backlog( +fn get_transaction_pool_backlog( state: CupratedRpcHandler, request: GetTransactionPoolBacklogRequest, -) -> GetTransactionPoolBacklogResponse { +) -> Result { todo!() } -async fn get_miner_data( +fn get_miner_data( state: CupratedRpcHandler, request: GetMinerDataRequest, -) -> GetMinerDataResponse { +) -> Result { todo!() } -async fn prune_blockchain( +fn prune_blockchain( state: CupratedRpcHandler, request: PruneBlockchainRequest, -) -> PruneBlockchainResponse { +) -> Result { todo!() } -async fn calc_pow(state: CupratedRpcHandler, request: CalcPowRequest) -> CalcPowResponse { +fn calc_pow( + state: CupratedRpcHandler, + request: CalcPowRequest, +) -> Result { todo!() } -async fn flush_cache(state: CupratedRpcHandler, request: FlushCacheRequest) -> FlushCacheResponse { +fn flush_cache( + state: CupratedRpcHandler, + request: FlushCacheRequest, +) -> Result { todo!() } -async fn add_aux_pow(state: CupratedRpcHandler, request: AddAuxPowRequest) -> AddAuxPowResponse { +fn add_aux_pow( + state: CupratedRpcHandler, + request: AddAuxPowRequest, +) -> Result { todo!() } -async fn get_tx_ids_loose( +fn get_tx_ids_loose( state: CupratedRpcHandler, request: GetTxIdsLooseRequest, -) -> GetTxIdsLooseResponse { +) -> Result { todo!() } diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index c570dfae6..6a84c650e 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -1,3 +1,4 @@ +use cuprate_rpc_interface::{RpcError, RpcResponse}; use cuprate_rpc_types::other::{ GetAltBlocksHashesRequest, GetAltBlocksHashesResponse, GetHeightRequest, GetHeightResponse, GetLimitRequest, GetLimitResponse, GetNetStatsRequest, GetNetStatsResponse, GetOutsRequest, @@ -6,211 +7,238 @@ use cuprate_rpc_types::other::{ GetTransactionPoolRequest, GetTransactionPoolResponse, GetTransactionPoolStatsRequest, GetTransactionPoolStatsResponse, GetTransactionsRequest, GetTransactionsResponse, InPeersRequest, InPeersResponse, IsKeyImageSpentRequest, IsKeyImageSpentResponse, - MiningStatusRequest, MiningStatusResponse, 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, + 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::CupratedRpcHandler; -pub(super) async fn map_request( - state: CupratedRpcHandler, - request: OtherRpcRequest, -) -> OtherRpcResponse { - use OtherRpcRequest as Req; - use OtherRpcResponse as Resp; - - match request { - Req::GetHeight(r) => Resp::GetHeight(get_height(state, r)), - Req::GetTransactions(r) => Resp::GetTransactions(get_transactions(state, r)), - Req::GetAltBlocksHashes(r) => Resp::GetAltBlocksHashes(get_alt_blocks_hashes(state, r)), - Req::IsKeyImageSpent(r) => Resp::IsKeyImageSpent(is_key_image_spent(state, r)), - Req::SendRawTransaction(r) => Resp::SendRawTransaction(send_raw_transaction(state, r)), - Req::StartMining(r) => Resp::StartMining(start_mining(state, r)), - Req::StopMining(r) => Resp::StopMining(stop_mining(state, r)), - Req::MiningStatus(r) => Resp::MiningStatus(mining_status(state, r)), - Req::SaveBc(r) => Resp::SaveBc(save_bc(state, r)), - Req::GetPeerList(r) => Resp::GetPeerList(get_peer_list(state, r)), - Req::SetLogHashRate(r) => Resp::SetLogHashRate(set_log_hash_rate(state, r)), - Req::SetLogLevel(r) => Resp::SetLogLevel(set_log_level(state, r)), - Req::SetLogCategories(r) => Resp::SetLogCategories(set_log_categories(state, r)), - Req::SetBootstrapDaemon(r) => Resp::SetBootstrapDaemon(set_bootstrap_daemon(state, r)), - Req::GetTransactionPool(r) => Resp::GetTransactionPool(get_transaction_pool(state, r)), +pub(super) fn map_request( + state: CupratedRpcHandler, + request: OtherRequest, +) -> Result { + use OtherRequest as Req; + use OtherResponse as Resp; + + Ok(match request { + Req::GetHeight(r) => Resp::GetHeight(get_height(state, r)?), + Req::GetTransactions(r) => Resp::GetTransactions(get_transactions(state, r)?), + Req::GetAltBlocksHashes(r) => Resp::GetAltBlocksHashes(get_alt_blocks_hashes(state, r)?), + Req::IsKeyImageSpent(r) => Resp::IsKeyImageSpent(is_key_image_spent(state, r)?), + Req::SendRawTransaction(r) => Resp::SendRawTransaction(send_raw_transaction(state, r)?), + Req::StartMining(r) => Resp::StartMining(start_mining(state, r)?), + Req::StopMining(r) => Resp::StopMining(stop_mining(state, r)?), + Req::MiningStatus(r) => Resp::MiningStatus(mining_status(state, r)?), + Req::SaveBc(r) => Resp::SaveBc(save_bc(state, r)?), + Req::GetPeerList(r) => Resp::GetPeerList(get_peer_list(state, r)?), + Req::SetLogHashRate(r) => Resp::SetLogHashRate(set_log_hash_rate(state, r)?), + Req::SetLogLevel(r) => Resp::SetLogLevel(set_log_level(state, r)?), + Req::SetLogCategories(r) => Resp::SetLogCategories(set_log_categories(state, r)?), + Req::SetBootstrapDaemon(r) => Resp::SetBootstrapDaemon(set_bootstrap_daemon(state, r)?), + Req::GetTransactionPool(r) => Resp::GetTransactionPool(get_transaction_pool(state, r)?), Req::GetTransactionPoolStats(r) => { - Resp::GetTransactionPoolStats(get_transaction_pool_stats(state, r)) + Resp::GetTransactionPoolStats(get_transaction_pool_stats(state, r)?) } - Req::StopDaemon(r) => Resp::StopDaemon(stop_daemon(state, r)), - Req::GetLimit(r) => Resp::GetLimit(get_limit(state, r)), - Req::SetLimit(r) => Resp::SetLimit(set_limit(state, r)), - Req::OutPeers(r) => Resp::OutPeers(out_peers(state, r)), - Req::InPeers(r) => Resp::InPeers(in_peers(state, r)), - Req::GetNetStats(r) => Resp::GetNetStats(get_net_stats(state, r)), - Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)), - Req::Update(r) => Resp::Update(update(state, r)), - Req::PopBlocks(r) => Resp::PopBlocks(pop_blocks(state, r)), + Req::StopDaemon(r) => Resp::StopDaemon(stop_daemon(state, r)?), + Req::GetLimit(r) => Resp::GetLimit(get_limit(state, r)?), + Req::SetLimit(r) => Resp::SetLimit(set_limit(state, r)?), + Req::OutPeers(r) => Resp::OutPeers(out_peers(state, r)?), + Req::InPeers(r) => Resp::InPeers(in_peers(state, r)?), + Req::GetNetStats(r) => Resp::GetNetStats(get_net_stats(state, r)?), + Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)?), + Req::Update(r) => Resp::Update(update(state, r)?), + Req::PopBlocks(r) => Resp::PopBlocks(pop_blocks(state, r)?), Req::GetTransactionPoolHashes(r) => { - Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r)) + Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r)?) } - Req::GetPublicNodes(r) => Resp::GetPublicNodes(get_public_nodes(state, r)), - } + Req::GetPublicNodes(r) => Resp::GetPublicNodes(get_public_nodes(state, r)?), + }) } -async fn get_height(state: CupratedRpcHandler, request: GetHeightRequest) -> GetHeightResponse { +fn get_height( + state: CupratedRpcHandler, + request: GetHeightRequest, +) -> Result { todo!() } -async fn get_transactions( +fn get_transactions( state: CupratedRpcHandler, request: GetTransactionsRequest, -) -> GetTransactionsResponse { +) -> Result { todo!() } -async fn get_alt_blocks_hashes( +fn get_alt_blocks_hashes( state: CupratedRpcHandler, request: GetAltBlocksHashesRequest, -) -> GetAltBlocksHashesResponse { +) -> Result { todo!() } -async fn is_key_image_spent( +fn is_key_image_spent( state: CupratedRpcHandler, request: IsKeyImageSpentRequest, -) -> IsKeyImageSpentResponse { +) -> Result { todo!() } -async fn send_raw_transaction( +fn send_raw_transaction( state: CupratedRpcHandler, request: SendRawTransactionRequest, -) -> SendRawTransactionResponse { +) -> Result { todo!() } -async fn start_mining( +fn start_mining( state: CupratedRpcHandler, request: StartMiningRequest, -) -> StartMiningResponse { +) -> Result { todo!() } -async fn stop_mining(state: CupratedRpcHandler, request: StopMiningRequest) -> StopMiningResponse { +fn stop_mining( + state: CupratedRpcHandler, + request: StopMiningRequest, +) -> Result { todo!() } -async fn mining_status( +fn mining_status( state: CupratedRpcHandler, request: MiningStatusRequest, -) -> MiningStatusResponse { +) -> Result { todo!() } -async fn save_bc(state: CupratedRpcHandler, request: SaveBcRequest) -> SaveBcResponse { +fn save_bc(state: CupratedRpcHandler, request: SaveBcRequest) -> Result { todo!() } -async fn get_peer_list( +fn get_peer_list( state: CupratedRpcHandler, request: GetPeerListRequest, -) -> GetPeerListResponse { +) -> Result { todo!() } -async fn set_log_hash_rate( +fn set_log_hash_rate( state: CupratedRpcHandler, request: SetLogHashRateRequest, -) -> SetLogHashRateResponse { +) -> Result { todo!() } -async fn set_log_level( +fn set_log_level( state: CupratedRpcHandler, request: SetLogLevelRequest, -) -> SetLogLevelResponse { +) -> Result { todo!() } -async fn set_log_categories( +fn set_log_categories( state: CupratedRpcHandler, request: SetLogCategoriesRequest, -) -> SetLogCategoriesResponse { +) -> Result { todo!() } -async fn set_bootstrap_daemon( +fn set_bootstrap_daemon( state: CupratedRpcHandler, request: SetBootstrapDaemonRequest, -) -> SetBootstrapDaemonResponse { +) -> Result { todo!() } -async fn get_transaction_pool( +fn get_transaction_pool( state: CupratedRpcHandler, request: GetTransactionPoolRequest, -) -> GetTransactionPoolResponse { +) -> Result { todo!() } -async fn get_transaction_pool_stats( +fn get_transaction_pool_stats( state: CupratedRpcHandler, request: GetTransactionPoolStatsRequest, -) -> GetTransactionPoolStatsResponse { +) -> Result { todo!() } -async fn stop_daemon(state: CupratedRpcHandler, request: StopDaemonRequest) -> StopDaemonResponse { +fn stop_daemon( + state: CupratedRpcHandler, + request: StopDaemonRequest, +) -> Result { todo!() } -async fn get_limit(state: CupratedRpcHandler, request: GetLimitRequest) -> GetLimitResponse { +fn get_limit( + state: CupratedRpcHandler, + request: GetLimitRequest, +) -> Result { todo!() } -async fn set_limit(state: CupratedRpcHandler, request: SetLimitRequest) -> SetLimitResponse { +fn set_limit( + state: CupratedRpcHandler, + request: SetLimitRequest, +) -> Result { todo!() } -async fn out_peers(state: CupratedRpcHandler, request: OutPeersRequest) -> OutPeersResponse { +fn out_peers( + state: CupratedRpcHandler, + request: OutPeersRequest, +) -> Result { todo!() } -async fn in_peers(state: CupratedRpcHandler, request: InPeersRequest) -> InPeersResponse { +fn in_peers( + state: CupratedRpcHandler, + request: InPeersRequest, +) -> Result { todo!() } -async fn get_net_stats( +fn get_net_stats( state: CupratedRpcHandler, request: GetNetStatsRequest, -) -> GetNetStatsResponse { +) -> Result { todo!() } -async fn get_outs(state: CupratedRpcHandler, request: GetOutsRequest) -> GetOutsResponse { +fn get_outs( + state: CupratedRpcHandler, + request: GetOutsRequest, +) -> Result { todo!() } -async fn update(state: CupratedRpcHandler, request: UpdateRequest) -> UpdateResponse { +fn update(state: CupratedRpcHandler, request: UpdateRequest) -> Result { todo!() } -async fn pop_blocks(state: CupratedRpcHandler, request: PopBlocksRequest) -> PopBlocksResponse { +fn pop_blocks( + state: CupratedRpcHandler, + request: PopBlocksRequest, +) -> Result { todo!() } -async fn get_transaction_pool_hashes( +fn get_transaction_pool_hashes( state: CupratedRpcHandler, request: GetTransactionPoolHashesRequest, -) -> GetTransactionPoolHashesResponse { +) -> Result { todo!() } -async fn get_public_nodes( +fn get_public_nodes( state: CupratedRpcHandler, request: GetPublicNodesRequest, -) -> GetPublicNodesResponse { +) -> Result { todo!() } diff --git a/rpc/interface/src/route/json_rpc.rs b/rpc/interface/src/route/json_rpc.rs index bd35e4375..28ab80c1b 100644 --- a/rpc/interface/src/route/json_rpc.rs +++ b/rpc/interface/src/route/json_rpc.rs @@ -50,7 +50,7 @@ pub(crate) async fn json_rpc( } // Send request. - let request = RpcRequest::JsonRpc(request); + let request = RpcRequest::JsonRpc(request.body); let channel = handler.oneshot(request).await?; // Assert the response from the inner handler is correct. @@ -58,6 +58,8 @@ pub(crate) async fn json_rpc( panic!("RPC handler returned incorrect response"); }; + let response = todo!(); + Ok(Json(response)) } diff --git a/rpc/interface/src/rpc_handler_dummy.rs b/rpc/interface/src/rpc_handler_dummy.rs index 73ffe9c8d..22c7fec41 100644 --- a/rpc/interface/src/rpc_handler_dummy.rs +++ b/rpc/interface/src/rpc_handler_dummy.rs @@ -62,7 +62,7 @@ impl Service for RpcHandlerDummy { #[rustfmt::skip] #[allow(clippy::default_trait_access)] let resp = match req { - RpcRequest::JsonRpc(j) => RpcResponse::JsonRpc(cuprate_json_rpc::Response::ok(Id::Null, match j.body { + RpcRequest::JsonRpc(j) => RpcResponse::JsonRpc(match j { JReq::GetBlockCount(_) => JResp::GetBlockCount(Default::default()), JReq::OnGetBlockHash(_) => JResp::OnGetBlockHash(Default::default()), JReq::SubmitBlock(_) => JResp::SubmitBlock(Default::default()), @@ -93,7 +93,7 @@ impl Service for RpcHandlerDummy { JReq::FlushCache(_) => JResp::FlushCache(Default::default()), JReq::AddAuxPow(_) => JResp::AddAuxPow(Default::default()), JReq::GetTxIdsLoose(_) => JResp::GetTxIdsLoose(Default::default()), - })), + }), RpcRequest::Binary(b) => RpcResponse::Binary(match b { BReq::GetBlocks(_) => BResp::GetBlocks(Default::default()), BReq::GetBlocksByHeight(_) => BResp::GetBlocksByHeight(Default::default()), diff --git a/rpc/interface/src/rpc_request.rs b/rpc/interface/src/rpc_request.rs index 3b66a780e..acac6dde8 100644 --- a/rpc/interface/src/rpc_request.rs +++ b/rpc/interface/src/rpc_request.rs @@ -19,7 +19,7 @@ use cuprate_rpc_types::{bin::BinRequest, json::JsonRpcRequest, other::OtherReque #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum RpcRequest { /// JSON-RPC 2.0 requests. - JsonRpc(cuprate_json_rpc::Request), + JsonRpc(JsonRpcRequest), /// Binary requests. Binary(BinRequest), /// Other JSON requests. diff --git a/rpc/interface/src/rpc_response.rs b/rpc/interface/src/rpc_response.rs index 7e8ecdbe9..8b6159586 100644 --- a/rpc/interface/src/rpc_response.rs +++ b/rpc/interface/src/rpc_response.rs @@ -19,7 +19,7 @@ use cuprate_rpc_types::{bin::BinResponse, json::JsonRpcResponse, other::OtherRes #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] pub enum RpcResponse { /// JSON RPC 2.0 responses. - JsonRpc(cuprate_json_rpc::Response), + JsonRpc(JsonRpcResponse), /// Binary responses. Binary(BinResponse), /// Other JSON responses. From c57020d805f06528ec7092de499a8f88ef7997db Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 2 Sep 2024 19:58:38 -0400 Subject: [PATCH 08/20] interface: handle json-rpc concepts --- binaries/cuprated/src/rpc.rs | 3 ++- binaries/cuprated/src/rpc/handler.rs | 3 --- rpc/interface/src/route/json_rpc.rs | 20 +++++++++----------- rpc/interface/src/rpc_handler_dummy.rs | 1 - rpc/interface/src/rpc_response.rs | 1 + 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 55051e1ae..43b68783c 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -2,7 +2,8 @@ //! //! Will contain the code to initiate the RPC and a request handler. -#![allow(clippy::needless_pass_by_value)] // TODO: remove after impl. +// TODO: remove after impl. +#![allow(dead_code, unused_variables, clippy::needless_pass_by_value)] mod bin; mod handler; diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 86897f134..ae9978265 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -63,8 +63,5 @@ impl Service for CupratedRpcHandler { }; todo!() - // let (tx, rx) = channel(); - // drop(tx.send(Ok(resp))); - // InfallibleOneshotReceiver::from(rx) } } diff --git a/rpc/interface/src/route/json_rpc.rs b/rpc/interface/src/route/json_rpc.rs index 28ab80c1b..16dc6005f 100644 --- a/rpc/interface/src/route/json_rpc.rs +++ b/rpc/interface/src/route/json_rpc.rs @@ -8,7 +8,7 @@ use tower::ServiceExt; use cuprate_json_rpc::{ error::{ErrorCode, ErrorObject}, - Id, + Id, Response, }; use cuprate_rpc_types::{ json::{JsonRpcRequest, JsonRpcResponse}, @@ -22,7 +22,7 @@ use crate::{rpc_handler::RpcHandler, rpc_request::RpcRequest, rpc_response::RpcR pub(crate) async fn json_rpc( State(handler): State, Json(request): Json>, -) -> Result>, StatusCode> { +) -> Result>, StatusCode> { // TODO: // // JSON-RPC notifications (requests without `id`) @@ -30,6 +30,11 @@ pub(crate) async fn json_rpc( // must remain. How to do this considering this function will // always return and cause `axum` to respond? + // JSON-RPC 2.0 rule: + // If there was an error in detecting the `Request`'s ID, + // the `Response` must contain an `Id::Null` + let id = request.id.unwrap_or(Id::Null); + // Return early if this RPC server is restricted and // the requested method is only for non-restricted RPC. if request.body.is_restricted() && handler.restricted() { @@ -39,12 +44,7 @@ pub(crate) async fn json_rpc( data: None, }; - // JSON-RPC 2.0 rule: - // If there was an error in detecting the `Request`'s ID, - // the `Response` must contain an `Id::Null` - let id = request.id.unwrap_or(Id::Null); - - let response = cuprate_json_rpc::Response::err(id, error_object); + let response = Response::err(id, error_object); return Ok(Json(response)); } @@ -58,9 +58,7 @@ pub(crate) async fn json_rpc( panic!("RPC handler returned incorrect response"); }; - let response = todo!(); - - Ok(Json(response)) + Ok(Json(Response::ok(id, response))) } //---------------------------------------------------------------------------------------------------- Tests diff --git a/rpc/interface/src/rpc_handler_dummy.rs b/rpc/interface/src/rpc_handler_dummy.rs index 22c7fec41..6a8532f7b 100644 --- a/rpc/interface/src/rpc_handler_dummy.rs +++ b/rpc/interface/src/rpc_handler_dummy.rs @@ -9,7 +9,6 @@ use serde::{Deserialize, Serialize}; use tower::Service; use cuprate_helper::asynch::InfallibleOneshotReceiver; -use cuprate_json_rpc::Id; use crate::{ rpc_error::RpcError, rpc_handler::RpcHandler, rpc_request::RpcRequest, diff --git a/rpc/interface/src/rpc_response.rs b/rpc/interface/src/rpc_response.rs index 8b6159586..23a0729ae 100644 --- a/rpc/interface/src/rpc_response.rs +++ b/rpc/interface/src/rpc_response.rs @@ -17,6 +17,7 @@ use cuprate_rpc_types::{bin::BinResponse, json::JsonRpcResponse, other::OtherRes /// It is the `Response` type required to be used in an [`RpcHandler`](crate::RpcHandler). #[derive(Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(Deserialize, Serialize))] +#[allow(clippy::large_enum_variant)] // FIXME: maybe don't wrap internally with an enum? pub enum RpcResponse { /// JSON RPC 2.0 responses. JsonRpc(JsonRpcResponse), From 68ba5f478124d6e98518078f9450315369111ab8 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 2 Sep 2024 20:15:12 -0400 Subject: [PATCH 09/20] split rpc calls into 3 `Service`s --- binaries/cuprated/src/rpc/handler.rs | 64 +++++--- rpc/interface/src/route/bin.rs | 7 +- rpc/interface/src/route/json_rpc.rs | 8 +- rpc/interface/src/route/other.rs | 8 +- rpc/interface/src/rpc_handler.rs | 23 ++- rpc/interface/src/rpc_handler_dummy.rs | 204 +++++++++++++++---------- 6 files changed, 194 insertions(+), 120 deletions(-) diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index ae9978265..2e15a5dfe 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -3,6 +3,11 @@ //---------------------------------------------------------------------------------------------------- Use use std::task::Poll; +use cuprate_rpc_types::{ + bin::{BinRequest, BinResponse}, + json::{JsonRpcRequest, JsonRpcResponse}, + other::{OtherRequest, OtherResponse}, +}; use futures::channel::oneshot::channel; use serde::{Deserialize, Serialize}; use tower::Service; @@ -36,32 +41,57 @@ impl RpcHandler for CupratedRpcHandler { } } -impl Service for CupratedRpcHandler { - type Response = RpcResponse; +// INVARIANT: +// +// We don't need to check for `self.is_restricted()` +// here because `cuprate-rpc-interface` handles that. +// +// We can assume the request coming has the required permissions. + +impl Service for CupratedRpcHandler { + type Response = JsonRpcResponse; type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Future = InfallibleOneshotReceiver>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) } - /// INVARIANT: - /// - /// We don't need to check for `self.is_restricted()` - /// here because `cuprate-rpc-interface` handles that. - /// - /// We can assume the request coming has the required permissions. - fn call(&mut self, req: RpcRequest) -> Self::Future { + fn call(&mut self, request: JsonRpcRequest) -> Self::Future { let state = Self::clone(self); + let response = json::map_request(state, request).expect("TODO"); + todo!() + } +} - let resp = match req { - RpcRequest::JsonRpc(r) => { - RpcResponse::JsonRpc(json::map_request(state, r).expect("TODO")) - } // JSON-RPC 2.0 requests. - RpcRequest::Binary(r) => RpcResponse::Binary(bin::map_request(state, r).expect("TODO")), // Binary requests. - RpcRequest::Other(r) => RpcResponse::Other(other::map_request(state, r).expect("TODO")), // JSON (but not JSON-RPC) requests. - }; +impl Service for CupratedRpcHandler { + type Response = BinResponse; + type Error = RpcError; + type Future = InfallibleOneshotReceiver>; + fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, request: BinRequest) -> Self::Future { + let state = Self::clone(self); + let response = bin::map_request(state, request).expect("TODO"); + todo!() + } +} + +impl Service for CupratedRpcHandler { + type Response = OtherResponse; + type Error = RpcError; + type Future = InfallibleOneshotReceiver>; + + fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, request: OtherRequest) -> Self::Future { + let state = Self::clone(self); + let response = other::map_request(state, request).expect("TODO"); todo!() } } diff --git a/rpc/interface/src/route/bin.rs b/rpc/interface/src/route/bin.rs index 942e0917c..c636d9c06 100644 --- a/rpc/interface/src/route/bin.rs +++ b/rpc/interface/src/route/bin.rs @@ -67,13 +67,8 @@ macro_rules! generate_endpoints_inner { paste::paste! { { // Send request. - let request = RpcRequest::Binary($request); - let channel = $handler.oneshot(request).await?; + let response = $handler.oneshot($request).await?; - // Assert the response from the inner handler is correct. - let RpcResponse::Binary(response) = channel else { - panic!("RPC handler did not return a binary response"); - }; let BinResponse::$variant(response) = response else { panic!("RPC handler returned incorrect response"); }; diff --git a/rpc/interface/src/route/json_rpc.rs b/rpc/interface/src/route/json_rpc.rs index 16dc6005f..db7749ec7 100644 --- a/rpc/interface/src/route/json_rpc.rs +++ b/rpc/interface/src/route/json_rpc.rs @@ -50,13 +50,7 @@ pub(crate) async fn json_rpc( } // Send request. - let request = RpcRequest::JsonRpc(request.body); - let channel = handler.oneshot(request).await?; - - // Assert the response from the inner handler is correct. - let RpcResponse::JsonRpc(response) = channel else { - panic!("RPC handler returned incorrect response"); - }; + let response = handler.oneshot(request.body).await?; Ok(Json(Response::ok(id, response))) } diff --git a/rpc/interface/src/route/other.rs b/rpc/interface/src/route/other.rs index ce778db98..26413820b 100644 --- a/rpc/interface/src/route/other.rs +++ b/rpc/interface/src/route/other.rs @@ -81,13 +81,9 @@ macro_rules! generate_endpoints_inner { } // Send request. - let request = RpcRequest::Other(OtherRequest::$variant($request)); - let channel = $handler.oneshot(request).await?; + let request = OtherRequest::$variant($request); + let response = $handler.oneshot(request).await?; - // Assert the response from the inner handler is correct. - let RpcResponse::Other(response) = channel else { - panic!("RPC handler did not return a binary response"); - }; let OtherResponse::$variant(response) = response else { panic!("RPC handler returned incorrect response") }; diff --git a/rpc/interface/src/rpc_handler.rs b/rpc/interface/src/rpc_handler.rs index bcd087331..b956586a1 100644 --- a/rpc/interface/src/rpc_handler.rs +++ b/rpc/interface/src/rpc_handler.rs @@ -3,6 +3,11 @@ //---------------------------------------------------------------------------------------------------- Use use std::future::Future; +use cuprate_rpc_types::{ + bin::{BinRequest, BinResponse}, + json::{JsonRpcRequest, JsonRpcResponse}, + other::{OtherRequest, OtherResponse}, +}; use tower::Service; use crate::{rpc_error::RpcError, rpc_request::RpcRequest, rpc_response::RpcResponse}; @@ -33,10 +38,22 @@ pub trait RpcHandler: + Sync + 'static + Service< - RpcRequest, - Response = RpcResponse, + JsonRpcRequest, + Response = JsonRpcResponse, Error = RpcError, - Future: Future> + Send + Sync + 'static, + Future: Future> + Send + Sync + 'static, + > + + Service< + OtherRequest, + Response = OtherResponse, + Error = RpcError, + Future: Future> + Send + Sync + 'static, + > + + Service< + BinRequest, + Response = BinResponse, + Error = RpcError, + Future: Future> + Send + Sync + 'static, > { /// Is this [`RpcHandler`] restricted? diff --git a/rpc/interface/src/rpc_handler_dummy.rs b/rpc/interface/src/rpc_handler_dummy.rs index 6a8532f7b..b01106bac 100644 --- a/rpc/interface/src/rpc_handler_dummy.rs +++ b/rpc/interface/src/rpc_handler_dummy.rs @@ -3,6 +3,11 @@ //---------------------------------------------------------------------------------------------------- Use use std::task::Poll; +use cuprate_rpc_types::{ + bin::{BinRequest, BinResponse}, + json::{JsonRpcRequest, JsonRpcResponse}, + other::{OtherRequest, OtherResponse}, +}; use futures::channel::oneshot::channel; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; @@ -41,96 +46,133 @@ impl RpcHandler for RpcHandlerDummy { } } -impl Service for RpcHandlerDummy { - type Response = RpcResponse; +impl Service for RpcHandlerDummy { + type Response = JsonRpcResponse; + type Error = RpcError; + type Future = InfallibleOneshotReceiver>; + + fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: JsonRpcRequest) -> Self::Future { + use cuprate_rpc_types::json::JsonRpcRequest as Req; + use cuprate_rpc_types::json::JsonRpcResponse as Resp; + + #[allow(clippy::default_trait_access)] + let resp = match req { + Req::GetBlockCount(_) => Resp::GetBlockCount(Default::default()), + Req::OnGetBlockHash(_) => Resp::OnGetBlockHash(Default::default()), + Req::SubmitBlock(_) => Resp::SubmitBlock(Default::default()), + Req::GenerateBlocks(_) => Resp::GenerateBlocks(Default::default()), + Req::GetLastBlockHeader(_) => Resp::GetLastBlockHeader(Default::default()), + Req::GetBlockHeaderByHash(_) => Resp::GetBlockHeaderByHash(Default::default()), + Req::GetBlockHeaderByHeight(_) => Resp::GetBlockHeaderByHeight(Default::default()), + Req::GetBlockHeadersRange(_) => Resp::GetBlockHeadersRange(Default::default()), + Req::GetBlock(_) => Resp::GetBlock(Default::default()), + Req::GetConnections(_) => Resp::GetConnections(Default::default()), + Req::GetInfo(_) => Resp::GetInfo(Default::default()), + Req::HardForkInfo(_) => Resp::HardForkInfo(Default::default()), + Req::SetBans(_) => Resp::SetBans(Default::default()), + Req::GetBans(_) => Resp::GetBans(Default::default()), + Req::Banned(_) => Resp::Banned(Default::default()), + Req::FlushTransactionPool(_) => Resp::FlushTransactionPool(Default::default()), + Req::GetOutputHistogram(_) => Resp::GetOutputHistogram(Default::default()), + Req::GetCoinbaseTxSum(_) => Resp::GetCoinbaseTxSum(Default::default()), + Req::GetVersion(_) => Resp::GetVersion(Default::default()), + Req::GetFeeEstimate(_) => Resp::GetFeeEstimate(Default::default()), + Req::GetAlternateChains(_) => Resp::GetAlternateChains(Default::default()), + Req::RelayTx(_) => Resp::RelayTx(Default::default()), + Req::SyncInfo(_) => Resp::SyncInfo(Default::default()), + Req::GetTransactionPoolBacklog(_) => { + Resp::GetTransactionPoolBacklog(Default::default()) + } + Req::GetMinerData(_) => Resp::GetMinerData(Default::default()), + Req::PruneBlockchain(_) => Resp::PruneBlockchain(Default::default()), + Req::CalcPow(_) => Resp::CalcPow(Default::default()), + Req::FlushCache(_) => Resp::FlushCache(Default::default()), + Req::AddAuxPow(_) => Resp::AddAuxPow(Default::default()), + Req::GetTxIdsLoose(_) => Resp::GetTxIdsLoose(Default::default()), + }; + + let (tx, rx) = channel(); + drop(tx.send(Ok(resp))); + InfallibleOneshotReceiver::from(rx) + } +} + +impl Service for RpcHandlerDummy { + type Response = BinResponse; + type Error = RpcError; + type Future = InfallibleOneshotReceiver>; + + fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + Poll::Ready(Ok(())) + } + + fn call(&mut self, req: BinRequest) -> Self::Future { + use cuprate_rpc_types::bin::BinRequest as Req; + use cuprate_rpc_types::bin::BinResponse as Resp; + + #[allow(clippy::default_trait_access)] + let resp = match req { + Req::GetBlocks(_) => Resp::GetBlocks(Default::default()), + Req::GetBlocksByHeight(_) => Resp::GetBlocksByHeight(Default::default()), + Req::GetHashes(_) => Resp::GetHashes(Default::default()), + Req::GetOutputIndexes(_) => Resp::GetOutputIndexes(Default::default()), + Req::GetOuts(_) => Resp::GetOuts(Default::default()), + Req::GetTransactionPoolHashes(_) => Resp::GetTransactionPoolHashes(Default::default()), + Req::GetOutputDistribution(_) => Resp::GetOutputDistribution(Default::default()), + }; + + let (tx, rx) = channel(); + drop(tx.send(Ok(resp))); + InfallibleOneshotReceiver::from(rx) + } +} + +impl Service for RpcHandlerDummy { + type Response = OtherResponse; type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Future = InfallibleOneshotReceiver>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) } - fn call(&mut self, req: RpcRequest) -> Self::Future { - use cuprate_rpc_types::bin::BinRequest as BReq; - use cuprate_rpc_types::bin::BinResponse as BResp; - use cuprate_rpc_types::json::JsonRpcRequest as JReq; - use cuprate_rpc_types::json::JsonRpcResponse as JResp; - use cuprate_rpc_types::other::OtherRequest as OReq; - use cuprate_rpc_types::other::OtherResponse as OResp; + fn call(&mut self, req: OtherRequest) -> Self::Future { + use cuprate_rpc_types::other::OtherRequest as Req; + use cuprate_rpc_types::other::OtherResponse as Resp; - #[rustfmt::skip] #[allow(clippy::default_trait_access)] let resp = match req { - RpcRequest::JsonRpc(j) => RpcResponse::JsonRpc(match j { - JReq::GetBlockCount(_) => JResp::GetBlockCount(Default::default()), - JReq::OnGetBlockHash(_) => JResp::OnGetBlockHash(Default::default()), - JReq::SubmitBlock(_) => JResp::SubmitBlock(Default::default()), - JReq::GenerateBlocks(_) => JResp::GenerateBlocks(Default::default()), - JReq::GetLastBlockHeader(_) => JResp::GetLastBlockHeader(Default::default()), - JReq::GetBlockHeaderByHash(_) => JResp::GetBlockHeaderByHash(Default::default()), - JReq::GetBlockHeaderByHeight(_) => JResp::GetBlockHeaderByHeight(Default::default()), - JReq::GetBlockHeadersRange(_) => JResp::GetBlockHeadersRange(Default::default()), - JReq::GetBlock(_) => JResp::GetBlock(Default::default()), - JReq::GetConnections(_) => JResp::GetConnections(Default::default()), - JReq::GetInfo(_) => JResp::GetInfo(Default::default()), - JReq::HardForkInfo(_) => JResp::HardForkInfo(Default::default()), - JReq::SetBans(_) => JResp::SetBans(Default::default()), - JReq::GetBans(_) => JResp::GetBans(Default::default()), - JReq::Banned(_) => JResp::Banned(Default::default()), - JReq::FlushTransactionPool(_) => JResp::FlushTransactionPool(Default::default()), - JReq::GetOutputHistogram(_) => JResp::GetOutputHistogram(Default::default()), - JReq::GetCoinbaseTxSum(_) => JResp::GetCoinbaseTxSum(Default::default()), - JReq::GetVersion(_) => JResp::GetVersion(Default::default()), - JReq::GetFeeEstimate(_) => JResp::GetFeeEstimate(Default::default()), - JReq::GetAlternateChains(_) => JResp::GetAlternateChains(Default::default()), - JReq::RelayTx(_) => JResp::RelayTx(Default::default()), - JReq::SyncInfo(_) => JResp::SyncInfo(Default::default()), - JReq::GetTransactionPoolBacklog(_) => JResp::GetTransactionPoolBacklog(Default::default()), - JReq::GetMinerData(_) => JResp::GetMinerData(Default::default()), - JReq::PruneBlockchain(_) => JResp::PruneBlockchain(Default::default()), - JReq::CalcPow(_) => JResp::CalcPow(Default::default()), - JReq::FlushCache(_) => JResp::FlushCache(Default::default()), - JReq::AddAuxPow(_) => JResp::AddAuxPow(Default::default()), - JReq::GetTxIdsLoose(_) => JResp::GetTxIdsLoose(Default::default()), - }), - RpcRequest::Binary(b) => RpcResponse::Binary(match b { - BReq::GetBlocks(_) => BResp::GetBlocks(Default::default()), - BReq::GetBlocksByHeight(_) => BResp::GetBlocksByHeight(Default::default()), - BReq::GetHashes(_) => BResp::GetHashes(Default::default()), - BReq::GetOutputIndexes(_) => BResp::GetOutputIndexes(Default::default()), - BReq::GetOuts(_) => BResp::GetOuts(Default::default()), - BReq::GetTransactionPoolHashes(_) => BResp::GetTransactionPoolHashes(Default::default()), - BReq::GetOutputDistribution(_) => BResp::GetOutputDistribution(Default::default()), - }), - RpcRequest::Other(o) => RpcResponse::Other(match o { - OReq::GetHeight(_) => OResp::GetHeight(Default::default()), - OReq::GetTransactions(_) => OResp::GetTransactions(Default::default()), - OReq::GetAltBlocksHashes(_) => OResp::GetAltBlocksHashes(Default::default()), - OReq::IsKeyImageSpent(_) => OResp::IsKeyImageSpent(Default::default()), - OReq::SendRawTransaction(_) => OResp::SendRawTransaction(Default::default()), - OReq::StartMining(_) => OResp::StartMining(Default::default()), - OReq::StopMining(_) => OResp::StopMining(Default::default()), - OReq::MiningStatus(_) => OResp::MiningStatus(Default::default()), - OReq::SaveBc(_) => OResp::SaveBc(Default::default()), - OReq::GetPeerList(_) => OResp::GetPeerList(Default::default()), - OReq::SetLogHashRate(_) => OResp::SetLogHashRate(Default::default()), - OReq::SetLogLevel(_) => OResp::SetLogLevel(Default::default()), - OReq::SetLogCategories(_) => OResp::SetLogCategories(Default::default()), - OReq::SetBootstrapDaemon(_) => OResp::SetBootstrapDaemon(Default::default()), - OReq::GetTransactionPool(_) => OResp::GetTransactionPool(Default::default()), - OReq::GetTransactionPoolStats(_) => OResp::GetTransactionPoolStats(Default::default()), - OReq::StopDaemon(_) => OResp::StopDaemon(Default::default()), - OReq::GetLimit(_) => OResp::GetLimit(Default::default()), - OReq::SetLimit(_) => OResp::SetLimit(Default::default()), - OReq::OutPeers(_) => OResp::OutPeers(Default::default()), - OReq::InPeers(_) => OResp::InPeers(Default::default()), - OReq::GetNetStats(_) => OResp::GetNetStats(Default::default()), - OReq::GetOuts(_) => OResp::GetOuts(Default::default()), - OReq::Update(_) => OResp::Update(Default::default()), - OReq::PopBlocks(_) => OResp::PopBlocks(Default::default()), - OReq::GetTransactionPoolHashes(_) => OResp::GetTransactionPoolHashes(Default::default()), - OReq::GetPublicNodes(_) => OResp::GetPublicNodes(Default::default()), - }) + Req::GetHeight(_) => Resp::GetHeight(Default::default()), + Req::GetTransactions(_) => Resp::GetTransactions(Default::default()), + Req::GetAltBlocksHashes(_) => Resp::GetAltBlocksHashes(Default::default()), + Req::IsKeyImageSpent(_) => Resp::IsKeyImageSpent(Default::default()), + Req::SendRawTransaction(_) => Resp::SendRawTransaction(Default::default()), + Req::StartMining(_) => Resp::StartMining(Default::default()), + Req::StopMining(_) => Resp::StopMining(Default::default()), + Req::MiningStatus(_) => Resp::MiningStatus(Default::default()), + Req::SaveBc(_) => Resp::SaveBc(Default::default()), + Req::GetPeerList(_) => Resp::GetPeerList(Default::default()), + Req::SetLogHashRate(_) => Resp::SetLogHashRate(Default::default()), + Req::SetLogLevel(_) => Resp::SetLogLevel(Default::default()), + Req::SetLogCategories(_) => Resp::SetLogCategories(Default::default()), + Req::SetBootstrapDaemon(_) => Resp::SetBootstrapDaemon(Default::default()), + Req::GetTransactionPool(_) => Resp::GetTransactionPool(Default::default()), + Req::GetTransactionPoolStats(_) => Resp::GetTransactionPoolStats(Default::default()), + Req::StopDaemon(_) => Resp::StopDaemon(Default::default()), + Req::GetLimit(_) => Resp::GetLimit(Default::default()), + Req::SetLimit(_) => Resp::SetLimit(Default::default()), + Req::OutPeers(_) => Resp::OutPeers(Default::default()), + Req::InPeers(_) => Resp::InPeers(Default::default()), + Req::GetNetStats(_) => Resp::GetNetStats(Default::default()), + Req::GetOuts(_) => Resp::GetOuts(Default::default()), + Req::Update(_) => Resp::Update(Default::default()), + Req::PopBlocks(_) => Resp::PopBlocks(Default::default()), + Req::GetTransactionPoolHashes(_) => Resp::GetTransactionPoolHashes(Default::default()), + Req::GetPublicNodes(_) => Resp::GetPublicNodes(Default::default()), }; let (tx, rx) = channel(); From 7487aa4779193f55d4b377f80574a16b57287eeb Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Mon, 2 Sep 2024 20:34:02 -0400 Subject: [PATCH 10/20] interface: extract out to `RpcService` --- binaries/cuprated/src/rpc/bin.rs | 2 +- binaries/cuprated/src/rpc/handler.rs | 2 +- binaries/cuprated/src/rpc/json.rs | 2 +- binaries/cuprated/src/rpc/other.rs | 2 +- rpc/interface/README.md | 18 +++++---- rpc/interface/src/lib.rs | 10 +++-- rpc/interface/src/route/bin.rs | 2 +- rpc/interface/src/route/json_rpc.rs | 2 +- rpc/interface/src/route/other.rs | 2 +- rpc/interface/src/rpc_handler.rs | 56 +++++++++----------------- rpc/interface/src/rpc_handler_dummy.rs | 5 +-- rpc/interface/src/rpc_service.rs | 49 ++++++++++++++++++++++ 12 files changed, 92 insertions(+), 60 deletions(-) create mode 100644 rpc/interface/src/rpc_service.rs diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs index a03808d71..6a3a781fc 100644 --- a/binaries/cuprated/src/rpc/bin.rs +++ b/binaries/cuprated/src/rpc/bin.rs @@ -1,4 +1,4 @@ -use cuprate_rpc_interface::{RpcError, RpcResponse}; +use cuprate_rpc_interface::RpcError; use cuprate_rpc_types::{ bin::{ BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksByHeightResponse, diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 2e15a5dfe..b475f29ac 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -15,7 +15,7 @@ use tower::Service; use cuprate_blockchain::service::BlockchainReadHandle; use cuprate_helper::asynch::InfallibleOneshotReceiver; use cuprate_json_rpc::Id; -use cuprate_rpc_interface::{RpcError, RpcHandler, RpcRequest, RpcResponse}; +use cuprate_rpc_interface::{RpcError, RpcHandler}; use cuprate_txpool::service::TxpoolReadHandle; use crate::rpc::{bin, json, other}; diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 70a9e497b..34c95342b 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use cuprate_rpc_interface::{RpcError, RpcResponse}; +use cuprate_rpc_interface::RpcError; use cuprate_rpc_types::json::{ AddAuxPowRequest, AddAuxPowResponse, BannedRequest, BannedResponse, CalcPowRequest, CalcPowResponse, FlushCacheRequest, FlushCacheResponse, FlushTransactionPoolRequest, diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index 6a84c650e..49d8415a6 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -1,4 +1,4 @@ -use cuprate_rpc_interface::{RpcError, RpcResponse}; +use cuprate_rpc_interface::RpcError; use cuprate_rpc_types::other::{ GetAltBlocksHashesRequest, GetAltBlocksHashesResponse, GetHeightRequest, GetHeightResponse, GetLimitRequest, GetLimitResponse, GetNetStatsRequest, GetNetStatsResponse, GetOutsRequest, diff --git a/rpc/interface/README.md b/rpc/interface/README.md index 3a63ac467..2d3faa754 100644 --- a/rpc/interface/README.md +++ b/rpc/interface/README.md @@ -17,7 +17,7 @@ CLIENT ─► ROUTE ─► REQUEST ─► HANDLER ─► RESPONSE ─► CLIENT Everything coming _in_ from a client is handled by this crate. -This is where your [`RpcHandler`] turns this [`RpcRequest`] into a [`RpcResponse`]. +This is where your [`RpcHandler`] turns this `Request` into a `Response`. You hand this `Response` back to `cuprate-rpc-interface` and it will take care of sending it back to the client. @@ -33,7 +33,7 @@ This crate simply handles: - Defining handler function signatures - (De)serialization of requests/responses (JSON-RPC, binary, JSON) -The actual server details are all handled by the [`axum`] and [`tower`] ecosystem. +The actual server details are all handled by the [`axum`] and [`tower`] ecosystem.a The proper usage of this crate is to: 1. Implement a [`RpcHandler`] @@ -42,16 +42,18 @@ The proper usage of this crate is to: 3. Do whatever with it # The [`RpcHandler`] -This is your [`tower::Service`] that converts [`RpcRequest`]s into [`RpcResponse`]s, +This is your [`tower::Service`] that converts `Request`s into `Response`s, i.e. the "inner handler". -Said concretely, `RpcHandler` is a `tower::Service` where the associated types are from this crate: -- [`RpcRequest`] -- [`RpcResponse`] +Said concretely, `RpcHandler` is 3 `tower::Service`s where the associated types are +the 3 endpoint enums from [`cuprate_rpc_types`] and the error type from this crate: +- [`JsonRpcRequest`](cuprate_rpc_types::json::JsonRpcRequest) & [`JsonRpcResponse`](cuprate_rpc_types::json::JsonRpcResponse) +- [`BinRequest`](cuprate_rpc_types::bin::BinRequest) & [`BinResponse`](cuprate_rpc_types::bin::BinRequest) +- [`OtherRequest`](cuprate_rpc_types::other::OtherRequest) & [`OtherResponse`](cuprate_rpc_types::other::OtherRequest) - [`RpcError`] `RpcHandler`'s [`Future`](std::future::Future) is generic, _although_, -it must output `Result`. +it must output `Result<$RESPONSE, RpcError>`. The `RpcHandler` must also hold some state that is required for RPC server operation. @@ -83,7 +85,7 @@ use cuprate_rpc_types::{ json::{JsonRpcRequest, JsonRpcResponse, GetBlockCountResponse}, other::{OtherRequest, OtherResponse}, }; -use cuprate_rpc_interface::{RouterBuilder, RpcHandlerDummy, RpcRequest}; +use cuprate_rpc_interface::{RouterBuilder, RpcHandlerDummy, Request}; // Send a `/get_height` request. This endpoint has no inputs. async fn get_height(port: u16) -> OtherResponse { diff --git a/rpc/interface/src/lib.rs b/rpc/interface/src/lib.rs index d43769797..f3e2988e6 100644 --- a/rpc/interface/src/lib.rs +++ b/rpc/interface/src/lib.rs @@ -7,16 +7,18 @@ mod rpc_error; mod rpc_handler; #[cfg(feature = "dummy")] mod rpc_handler_dummy; -mod rpc_request; -mod rpc_response; +// mod rpc_request; +// mod rpc_response; +mod rpc_service; pub use router_builder::RouterBuilder; pub use rpc_error::RpcError; pub use rpc_handler::RpcHandler; #[cfg(feature = "dummy")] pub use rpc_handler_dummy::RpcHandlerDummy; -pub use rpc_request::RpcRequest; -pub use rpc_response::RpcResponse; +// pub use rpc_request::RpcRequest; +// pub use rpc_response::RpcResponse; +pub use rpc_service::RpcService; // false-positive: used in `README.md`'s doc-test. #[cfg(test)] diff --git a/rpc/interface/src/route/bin.rs b/rpc/interface/src/route/bin.rs index c636d9c06..45447caf7 100644 --- a/rpc/interface/src/route/bin.rs +++ b/rpc/interface/src/route/bin.rs @@ -7,7 +7,7 @@ use tower::ServiceExt; use cuprate_epee_encoding::from_bytes; use cuprate_rpc_types::bin::{BinRequest, BinResponse, GetTransactionPoolHashesRequest}; -use crate::{rpc_handler::RpcHandler, rpc_request::RpcRequest, rpc_response::RpcResponse}; +use crate::rpc_handler::RpcHandler; //---------------------------------------------------------------------------------------------------- Routes /// This macro generates route functions that expect input. diff --git a/rpc/interface/src/route/json_rpc.rs b/rpc/interface/src/route/json_rpc.rs index db7749ec7..bf3d937db 100644 --- a/rpc/interface/src/route/json_rpc.rs +++ b/rpc/interface/src/route/json_rpc.rs @@ -15,7 +15,7 @@ use cuprate_rpc_types::{ RpcCallValue, }; -use crate::{rpc_handler::RpcHandler, rpc_request::RpcRequest, rpc_response::RpcResponse}; +use crate::rpc_handler::RpcHandler; //---------------------------------------------------------------------------------------------------- Routes /// The `/json_rpc` route function used in [`crate::RouterBuilder`]. diff --git a/rpc/interface/src/route/other.rs b/rpc/interface/src/route/other.rs index 26413820b..129ddd593 100644 --- a/rpc/interface/src/route/other.rs +++ b/rpc/interface/src/route/other.rs @@ -25,7 +25,7 @@ use cuprate_rpc_types::{ RpcCall, }; -use crate::{rpc_handler::RpcHandler, rpc_request::RpcRequest, rpc_response::RpcResponse}; +use crate::rpc_handler::RpcHandler; //---------------------------------------------------------------------------------------------------- Routes /// This macro generates route functions that expect input. diff --git a/rpc/interface/src/rpc_handler.rs b/rpc/interface/src/rpc_handler.rs index b956586a1..f4c9fb568 100644 --- a/rpc/interface/src/rpc_handler.rs +++ b/rpc/interface/src/rpc_handler.rs @@ -1,60 +1,42 @@ //! RPC handler trait. //---------------------------------------------------------------------------------------------------- Use -use std::future::Future; - use cuprate_rpc_types::{ bin::{BinRequest, BinResponse}, json::{JsonRpcRequest, JsonRpcResponse}, other::{OtherRequest, OtherResponse}, }; -use tower::Service; -use crate::{rpc_error::RpcError, rpc_request::RpcRequest, rpc_response::RpcResponse}; +use crate::RpcService; //---------------------------------------------------------------------------------------------------- RpcHandler /// An RPC handler. /// -/// This trait represents a type that can turn [`RpcRequest`]s into [`RpcResponse`]s. +/// This trait represents a type that can turn `Request`s into `Response`s. +/// +/// Implementors of this trait must be: +/// - A [`tower::Service`]s that use [`JsonRpcRequest`] & [`JsonRpcResponse`] +/// - A [`tower::Service`]s that use [`BinRequest`] & [`BinResponse`] +/// - A [`tower::Service`]s that use [`OtherRequest`] & [`OtherResponse`] +/// +/// In other words, an [`RpcHandler`] is a type that implements [`tower::Service`] 3 times, +/// one for each endpoint enum type found in [`cuprate_rpc_types`]. /// -/// Implementors of this trait must be [`tower::Service`]s that use: -/// - [`RpcRequest`] as the generic `Request` type -/// - [`RpcResponse`] as the associated `Response` type -/// - [`RpcError`] as the associated `Error` type -/// - A generic [`Future`] that outputs `Result` +/// The error type must always be [`RpcError`](crate::RpcError). /// /// See this crate's `RpcHandlerDummy` for an implementation example of this trait. /// /// # Panics -/// Your [`RpcHandler`] must reply to [`RpcRequest`]s with the correct -/// [`RpcResponse`] or else this crate will panic during routing functions. +/// Your [`RpcHandler`] must reply to `Request`s with the correct +/// `Response` or else this crate will panic during routing functions. /// -/// For example, upon a [`RpcRequest::Binary`] must be replied with -/// [`RpcRequest::Binary`]. If an [`RpcRequest::Other`] were returned instead, -/// this crate would panic. +/// For example, upon a [`JsonRpcRequest::GetBlockCount`] must be replied with +/// [`JsonRpcResponse::GetBlockCount`]. If anything else is returned, +/// this crate may panic. pub trait RpcHandler: - Clone - + Send - + Sync - + 'static - + Service< - JsonRpcRequest, - Response = JsonRpcResponse, - Error = RpcError, - Future: Future> + Send + Sync + 'static, - > - + Service< - OtherRequest, - Response = OtherResponse, - Error = RpcError, - Future: Future> + Send + Sync + 'static, - > - + Service< - BinRequest, - Response = BinResponse, - Error = RpcError, - Future: Future> + Send + Sync + 'static, - > + RpcService + + RpcService + + RpcService { /// Is this [`RpcHandler`] restricted? /// diff --git a/rpc/interface/src/rpc_handler_dummy.rs b/rpc/interface/src/rpc_handler_dummy.rs index b01106bac..06fa4608b 100644 --- a/rpc/interface/src/rpc_handler_dummy.rs +++ b/rpc/interface/src/rpc_handler_dummy.rs @@ -15,10 +15,7 @@ use tower::Service; use cuprate_helper::asynch::InfallibleOneshotReceiver; -use crate::{ - rpc_error::RpcError, rpc_handler::RpcHandler, rpc_request::RpcRequest, - rpc_response::RpcResponse, -}; +use crate::{rpc_error::RpcError, rpc_handler::RpcHandler}; //---------------------------------------------------------------------------------------------------- RpcHandlerDummy /// An [`RpcHandler`] that always returns [`Default::default`]. diff --git a/rpc/interface/src/rpc_service.rs b/rpc/interface/src/rpc_service.rs new file mode 100644 index 000000000..cd250035a --- /dev/null +++ b/rpc/interface/src/rpc_service.rs @@ -0,0 +1,49 @@ +//! RPC [`tower::Service`] trait. + +//---------------------------------------------------------------------------------------------------- Use +use std::future::Future; + +use tower::Service; + +use crate::rpc_error::RpcError; + +//---------------------------------------------------------------------------------------------------- RpcService +/// An RPC [`tower::Service`]. +/// +/// This trait solely exists to encapsulate the traits needed +/// to handle RPC requests and respond with responses - **it is +/// not meant to be used directly.** +/// +/// The `Request` and `Response` are generic and +/// are used in the [`tower::Service`] bounds. +/// +/// The error type is always [`RpcError`]. +/// +/// See [`RpcHandler`](crate::RpcHandler) for more information. +pub trait RpcService: + Clone + + Send + + Sync + + 'static + + Service< + Request, + Response = Response, + Error = RpcError, + Future: Future> + Send + Sync + 'static, + > +{ +} + +impl RpcService for T where + Self: Clone + + Send + + Sync + + 'static + + Service< + Request, + Response = Response, + Error = RpcError, + Future: Future> + Send + Sync + 'static, + > +{ +} From 4118f488bfde33af64bc98578d4267409cf3631c Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 5 Sep 2024 17:19:57 -0400 Subject: [PATCH 11/20] fix merge --- rpc/interface/README.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/rpc/interface/README.md b/rpc/interface/README.md index 59d9f04c8..e8be2d0da 100644 --- a/rpc/interface/README.md +++ b/rpc/interface/README.md @@ -85,13 +85,7 @@ use cuprate_rpc_types::{ json::{JsonRpcRequest, JsonRpcResponse, GetBlockCountResponse}, other::{OtherRequest, OtherResponse}, }; -<<<<<<< HEAD -use cuprate_rpc_interface::{RouterBuilder, RpcHandlerDummy, Request}; -||||||| 0941f68 -use cuprate_rpc_interface::{RouterBuilder, RpcHandlerDummy, RpcRequest}; -======= use cuprate_rpc_interface::{RouterBuilder, RpcHandlerDummy}; ->>>>>>> main // Send a `/get_height` request. This endpoint has no inputs. async fn get_height(port: u16) -> OtherResponse { From 29afe237d56e3fa469c7deb3990173f48dac5353 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 5 Sep 2024 17:38:57 -0400 Subject: [PATCH 12/20] remove crate lints --- binaries/cuprated/src/main.rs | 95 ++--------------------------------- 1 file changed, 4 insertions(+), 91 deletions(-) diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index 9c59a5673..e1b18c58f 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -1,98 +1,11 @@ #![doc = include_str!("../README.md")] #![cfg_attr(docsrs, feature(doc_cfg))] -//---------------------------------------------------------------------------------------------------- Lints -// Forbid lints. -// Our code, and code generated (e.g macros) cannot overrule these. -#![forbid( - // `unsafe` is allowed but it _must_ be - // commented with `SAFETY: reason`. - clippy::undocumented_unsafe_blocks, - - // Never. - unused_unsafe, - redundant_semicolons, - unused_allocation, - coherence_leak_check, - - // Maybe can be put into `#[deny]`. - unconditional_recursion, - for_loops_over_fallibles, - unused_braces, - unused_labels, - keyword_idents, - non_ascii_idents, - variant_size_differences, - single_use_lifetimes, - - // Probably can be put into `#[deny]`. - future_incompatible, - let_underscore, - break_with_label_and_loop, - duplicate_macro_attributes, - exported_private_dependencies, - large_assignments, - overlapping_range_endpoints, - semicolon_in_expressions_from_macros, - noop_method_call, -)] -// Deny lints. -// Some of these are `#[allow]`'ed on a per-case basis. -#![deny( - clippy::all, - clippy::correctness, - clippy::suspicious, - clippy::style, - clippy::complexity, - clippy::perf, - clippy::pedantic, - clippy::nursery, - clippy::cargo, - unused_doc_comments, - unused_mut, - missing_docs, - deprecated, - unused_comparisons, - nonstandard_style, - // unreachable_pub -)] #![allow( - // FIXME: this lint affects crates outside of - // `database/` for some reason, allow for now. - clippy::cargo_common_metadata, - - // FIXME: adding `#[must_use]` onto everything - // might just be more annoying than useful... - // although it is sometimes nice. - clippy::must_use_candidate, - - // FIXME: good lint but too many false positives - // with our `Env` + `RwLock` setup. - clippy::significant_drop_tightening, - - // FIXME: good lint but is less clear in most cases. - clippy::items_after_statements, - - // TODO - rustdoc::bare_urls, - - clippy::multiple_crate_versions, - clippy::module_name_repetitions, - clippy::module_inception, - clippy::redundant_pub_crate, - clippy::option_if_let_else, -)] -// Allow some lints in tests. -#![cfg_attr( - test, - allow( - clippy::cognitive_complexity, - clippy::needless_pass_by_value, - clippy::cast_possible_truncation, - clippy::too_many_lines - ) + unused_imports, + unreachable_pub, + unused_crate_dependencies, + reason = "TODO: remove after v1.0.0" )] -// TODO: remove after debug and/or v1.0.0 impl. -#![allow(unused_imports, unreachable_pub, unused_crate_dependencies)] mod blockchain; mod config; From 7406afb9105502c88664548e1e50964ce6c3fabb Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 5 Sep 2024 18:06:07 -0400 Subject: [PATCH 13/20] use `BoxFuture` --- binaries/cuprated/src/main.rs | 4 + binaries/cuprated/src/rpc.rs | 1 - binaries/cuprated/src/rpc/bin.rs | 31 ++++--- binaries/cuprated/src/rpc/handler.rs | 20 ++-- binaries/cuprated/src/rpc/json.rs | 133 +++++++++++++++------------ binaries/cuprated/src/rpc/other.rs | 125 ++++++++++++++----------- 6 files changed, 169 insertions(+), 145 deletions(-) diff --git a/binaries/cuprated/src/main.rs b/binaries/cuprated/src/main.rs index e1b18c58f..76eb85e8d 100644 --- a/binaries/cuprated/src/main.rs +++ b/binaries/cuprated/src/main.rs @@ -4,6 +4,10 @@ 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" )] diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 43b68783c..1b483a936 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -3,7 +3,6 @@ //! Will contain the code to initiate the RPC and a request handler. // TODO: remove after impl. -#![allow(dead_code, unused_variables, clippy::needless_pass_by_value)] mod bin; mod handler; diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs index 6a3a781fc..a429ad342 100644 --- a/binaries/cuprated/src/rpc/bin.rs +++ b/binaries/cuprated/src/rpc/bin.rs @@ -11,7 +11,8 @@ use cuprate_rpc_types::{ use crate::rpc::CupratedRpcHandler; -pub(super) fn map_request( +/// Map a [`BinRequest`] to the function that will lead to a [`BinResponse`]. +pub(super) async fn map_request( state: CupratedRpcHandler, request: BinRequest, ) -> Result { @@ -19,63 +20,63 @@ pub(super) fn map_request( use BinResponse as Resp; Ok(match request { - Req::GetBlocks(r) => Resp::GetBlocks(get_blocks(state, r)?), - Req::GetBlocksByHeight(r) => Resp::GetBlocksByHeight(get_blocks_by_height(state, r)?), - Req::GetHashes(r) => Resp::GetHashes(get_hashes(state, r)?), - Req::GetOutputIndexes(r) => Resp::GetOutputIndexes(get_output_indexes(state, r)?), - Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)?), + 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)?) + Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r).await?) } Req::GetOutputDistribution(r) => { - Resp::GetOutputDistribution(get_output_distribution(state, r)?) + Resp::GetOutputDistribution(get_output_distribution(state, r).await?) } }) } -fn get_blocks( +async fn get_blocks( state: CupratedRpcHandler, request: GetBlocksRequest, ) -> Result { todo!() } -fn get_blocks_by_height( +async fn get_blocks_by_height( state: CupratedRpcHandler, request: GetBlocksByHeightRequest, ) -> Result { todo!() } -fn get_hashes( +async fn get_hashes( state: CupratedRpcHandler, request: GetHashesRequest, ) -> Result { todo!() } -fn get_output_indexes( +async fn get_output_indexes( state: CupratedRpcHandler, request: GetOutputIndexesRequest, ) -> Result { todo!() } -fn get_outs( +async fn get_outs( state: CupratedRpcHandler, request: GetOutsRequest, ) -> Result { todo!() } -fn get_transaction_pool_hashes( +async fn get_transaction_pool_hashes( state: CupratedRpcHandler, request: GetTransactionPoolHashesRequest, ) -> Result { todo!() } -fn get_output_distribution( +async fn get_output_distribution( state: CupratedRpcHandler, request: GetOutputDistributionRequest, ) -> Result { diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index b475f29ac..2f5b35db5 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -1,6 +1,5 @@ //! Dummy implementation of [`RpcHandler`]. -//---------------------------------------------------------------------------------------------------- Use use std::task::Poll; use cuprate_rpc_types::{ @@ -8,7 +7,7 @@ use cuprate_rpc_types::{ json::{JsonRpcRequest, JsonRpcResponse}, other::{OtherRequest, OtherResponse}, }; -use futures::channel::oneshot::channel; +use futures::{channel::oneshot::channel, future::BoxFuture}; use serde::{Deserialize, Serialize}; use tower::Service; @@ -20,7 +19,6 @@ use cuprate_txpool::service::TxpoolReadHandle; use crate::rpc::{bin, json, other}; -//---------------------------------------------------------------------------------------------------- CupratedRpcHandler /// TODO #[derive(Clone)] pub struct CupratedRpcHandler { @@ -34,7 +32,6 @@ pub struct CupratedRpcHandler { pub txpool: TxpoolReadHandle, } -//---------------------------------------------------------------------------------------------------- RpcHandler Impl impl RpcHandler for CupratedRpcHandler { fn restricted(&self) -> bool { self.restricted @@ -51,7 +48,7 @@ impl RpcHandler for CupratedRpcHandler { impl Service for CupratedRpcHandler { type Response = JsonRpcResponse; type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -59,15 +56,14 @@ impl Service for CupratedRpcHandler { fn call(&mut self, request: JsonRpcRequest) -> Self::Future { let state = Self::clone(self); - let response = json::map_request(state, request).expect("TODO"); - todo!() + Box::pin(json::map_request(state, request)) } } impl Service for CupratedRpcHandler { type Response = BinResponse; type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -75,15 +71,14 @@ impl Service for CupratedRpcHandler { fn call(&mut self, request: BinRequest) -> Self::Future { let state = Self::clone(self); - let response = bin::map_request(state, request).expect("TODO"); - todo!() + Box::pin(bin::map_request(state, request)) } } impl Service for CupratedRpcHandler { type Response = OtherResponse; type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -91,7 +86,6 @@ impl Service for CupratedRpcHandler { fn call(&mut self, request: OtherRequest) -> Self::Future { let state = Self::clone(self); - let response = other::map_request(state, request).expect("TODO"); - todo!() + Box::pin(other::map_request(state, request)) } } diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 34c95342b..95bc94b3e 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -20,10 +20,12 @@ use cuprate_rpc_types::json::{ RelayTxResponse, SetBansRequest, SetBansResponse, SubmitBlockRequest, SubmitBlockResponse, SyncInfoRequest, SyncInfoResponse, }; +use tower::ServiceExt; use crate::rpc::CupratedRpcHandler; -pub(super) fn map_request( +/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`]. +pub(super) async fn map_request( state: CupratedRpcHandler, request: JsonRpcRequest, ) -> Result { @@ -31,250 +33,259 @@ pub(super) fn map_request( use JsonRpcResponse as Resp; Ok(match request { - Req::GetBlockCount(r) => Resp::GetBlockCount(get_block_count(state, r)?), - Req::OnGetBlockHash(r) => Resp::OnGetBlockHash(on_get_block_hash(state, r)?), - Req::SubmitBlock(r) => Resp::SubmitBlock(submit_block(state, r)?), - Req::GenerateBlocks(r) => Resp::GenerateBlocks(generate_blocks(state, r)?), - Req::GetLastBlockHeader(r) => Resp::GetLastBlockHeader(get_last_block_header(state, r)?), + 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)?) + Resp::GetBlockHeaderByHash(get_block_header_by_hash(state, r).await?) } Req::GetBlockHeaderByHeight(r) => { - Resp::GetBlockHeaderByHeight(get_block_header_by_height(state, r)?) + Resp::GetBlockHeaderByHeight(get_block_header_by_height(state, r).await?) } Req::GetBlockHeadersRange(r) => { - Resp::GetBlockHeadersRange(get_block_headers_range(state, r)?) + Resp::GetBlockHeadersRange(get_block_headers_range(state, r).await?) } - Req::GetBlock(r) => Resp::GetBlock(get_block(state, r)?), - Req::GetConnections(r) => Resp::GetConnections(get_connections(state, r)?), - Req::GetInfo(r) => Resp::GetInfo(get_info(state, r)?), - Req::HardForkInfo(r) => Resp::HardForkInfo(hard_fork_info(state, r)?), - Req::SetBans(r) => Resp::SetBans(set_bans(state, r)?), - Req::GetBans(r) => Resp::GetBans(get_bans(state, r)?), - Req::Banned(r) => Resp::Banned(banned(state, r)?), + 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)?) + Resp::FlushTransactionPool(flush_transaction_pool(state, r).await?) + } + Req::GetOutputHistogram(r) => { + Resp::GetOutputHistogram(get_output_histogram(state, r).await?) } - Req::GetOutputHistogram(r) => Resp::GetOutputHistogram(get_output_histogram(state, r)?), - Req::GetCoinbaseTxSum(r) => Resp::GetCoinbaseTxSum(get_coinbase_tx_sum(state, r)?), - Req::GetVersion(r) => Resp::GetVersion(get_version(state, r)?), - Req::GetFeeEstimate(r) => Resp::GetFeeEstimate(get_fee_estimate(state, r)?), - Req::GetAlternateChains(r) => Resp::GetAlternateChains(get_alternate_chains(state, r)?), - Req::RelayTx(r) => Resp::RelayTx(relay_tx(state, r)?), - Req::SyncInfo(r) => Resp::SyncInfo(sync_info(state, r)?), + 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)?) + Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r).await?) } - Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r)?), - Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r)?), - Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r)?), - Req::FlushCache(r) => Resp::FlushCache(flush_cache(state, r)?), - Req::AddAuxPow(r) => Resp::AddAuxPow(add_aux_pow(state, r)?), - Req::GetTxIdsLoose(r) => Resp::GetTxIdsLoose(get_tx_ids_loose(state, r)?), + 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?), }) } -fn get_block_count( +async fn get_block_count( state: CupratedRpcHandler, request: GetBlockCountRequest, ) -> Result { todo!() } -fn on_get_block_hash( +async fn on_get_block_hash( state: CupratedRpcHandler, request: OnGetBlockHashRequest, ) -> Result { todo!() } -fn submit_block( +async fn submit_block( state: CupratedRpcHandler, request: SubmitBlockRequest, ) -> Result { todo!() } -fn generate_blocks( +async fn generate_blocks( state: CupratedRpcHandler, request: GenerateBlocksRequest, ) -> Result { todo!() } -fn get_last_block_header( +async fn get_last_block_header( state: CupratedRpcHandler, request: GetLastBlockHeaderRequest, ) -> Result { todo!() } -fn get_block_header_by_hash( +async fn get_block_header_by_hash( state: CupratedRpcHandler, request: GetBlockHeaderByHashRequest, ) -> Result { todo!() } -fn get_block_header_by_height( +async fn get_block_header_by_height( state: CupratedRpcHandler, request: GetBlockHeaderByHeightRequest, ) -> Result { todo!() } -fn get_block_headers_range( +async fn get_block_headers_range( state: CupratedRpcHandler, request: GetBlockHeadersRangeRequest, ) -> Result { todo!() } -fn get_block( +async fn get_block( state: CupratedRpcHandler, request: GetBlockRequest, ) -> Result { todo!() } -fn get_connections( +async fn get_connections( state: CupratedRpcHandler, request: GetConnectionsRequest, ) -> Result { todo!() } -fn get_info( +async fn get_info( state: CupratedRpcHandler, request: GetInfoRequest, ) -> Result { todo!() } -fn hard_fork_info( +async fn hard_fork_info( state: CupratedRpcHandler, request: HardForkInfoRequest, ) -> Result { todo!() } -fn set_bans( +async fn set_bans( state: CupratedRpcHandler, request: SetBansRequest, ) -> Result { todo!() } -fn get_bans( +async fn get_bans( state: CupratedRpcHandler, request: GetBansRequest, ) -> Result { todo!() } -fn banned(state: CupratedRpcHandler, request: BannedRequest) -> Result { +async fn banned( + state: CupratedRpcHandler, + request: BannedRequest, +) -> Result { todo!() } -fn flush_transaction_pool( +async fn flush_transaction_pool( state: CupratedRpcHandler, request: FlushTransactionPoolRequest, ) -> Result { todo!() } -fn get_output_histogram( +async fn get_output_histogram( state: CupratedRpcHandler, request: GetOutputHistogramRequest, ) -> Result { todo!() } -fn get_coinbase_tx_sum( +async fn get_coinbase_tx_sum( state: CupratedRpcHandler, request: GetCoinbaseTxSumRequest, ) -> Result { todo!() } -fn get_version( +async fn get_version( state: CupratedRpcHandler, request: GetVersionRequest, ) -> Result { todo!() } -fn get_fee_estimate( +async fn get_fee_estimate( state: CupratedRpcHandler, request: GetFeeEstimateRequest, ) -> Result { todo!() } -fn get_alternate_chains( +async fn get_alternate_chains( state: CupratedRpcHandler, request: GetAlternateChainsRequest, ) -> Result { todo!() } -fn relay_tx( +async fn relay_tx( state: CupratedRpcHandler, request: RelayTxRequest, ) -> Result { todo!() } -fn sync_info( +async fn sync_info( state: CupratedRpcHandler, request: SyncInfoRequest, ) -> Result { todo!() } -fn get_transaction_pool_backlog( +async fn get_transaction_pool_backlog( state: CupratedRpcHandler, request: GetTransactionPoolBacklogRequest, ) -> Result { todo!() } -fn get_miner_data( +async fn get_miner_data( state: CupratedRpcHandler, request: GetMinerDataRequest, ) -> Result { todo!() } -fn prune_blockchain( +async fn prune_blockchain( state: CupratedRpcHandler, request: PruneBlockchainRequest, ) -> Result { todo!() } -fn calc_pow( +async fn calc_pow( state: CupratedRpcHandler, request: CalcPowRequest, ) -> Result { todo!() } -fn flush_cache( +async fn flush_cache( state: CupratedRpcHandler, request: FlushCacheRequest, ) -> Result { todo!() } -fn add_aux_pow( +async fn add_aux_pow( state: CupratedRpcHandler, request: AddAuxPowRequest, ) -> Result { todo!() } -fn get_tx_ids_loose( +async fn get_tx_ids_loose( state: CupratedRpcHandler, request: GetTxIdsLooseRequest, ) -> Result { diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index 49d8415a6..c876e5425 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -18,7 +18,8 @@ use cuprate_rpc_types::other::{ use crate::rpc::CupratedRpcHandler; -pub(super) fn map_request( +/// Map a [`OtherRequest`] to the function that will lead to a [`OtherResponse`]. +pub(super) async fn map_request( state: CupratedRpcHandler, request: OtherRequest, ) -> Result { @@ -26,217 +27,231 @@ pub(super) fn map_request( use OtherResponse as Resp; Ok(match request { - Req::GetHeight(r) => Resp::GetHeight(get_height(state, r)?), - Req::GetTransactions(r) => Resp::GetTransactions(get_transactions(state, r)?), - Req::GetAltBlocksHashes(r) => Resp::GetAltBlocksHashes(get_alt_blocks_hashes(state, r)?), - Req::IsKeyImageSpent(r) => Resp::IsKeyImageSpent(is_key_image_spent(state, r)?), - Req::SendRawTransaction(r) => Resp::SendRawTransaction(send_raw_transaction(state, r)?), - Req::StartMining(r) => Resp::StartMining(start_mining(state, r)?), - Req::StopMining(r) => Resp::StopMining(stop_mining(state, r)?), - Req::MiningStatus(r) => Resp::MiningStatus(mining_status(state, r)?), - Req::SaveBc(r) => Resp::SaveBc(save_bc(state, r)?), - Req::GetPeerList(r) => Resp::GetPeerList(get_peer_list(state, r)?), - Req::SetLogHashRate(r) => Resp::SetLogHashRate(set_log_hash_rate(state, r)?), - Req::SetLogLevel(r) => Resp::SetLogLevel(set_log_level(state, r)?), - Req::SetLogCategories(r) => Resp::SetLogCategories(set_log_categories(state, r)?), - Req::SetBootstrapDaemon(r) => Resp::SetBootstrapDaemon(set_bootstrap_daemon(state, r)?), - Req::GetTransactionPool(r) => Resp::GetTransactionPool(get_transaction_pool(state, r)?), + 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)?) + Resp::GetTransactionPoolStats(get_transaction_pool_stats(state, r).await?) } - Req::StopDaemon(r) => Resp::StopDaemon(stop_daemon(state, r)?), - Req::GetLimit(r) => Resp::GetLimit(get_limit(state, r)?), - Req::SetLimit(r) => Resp::SetLimit(set_limit(state, r)?), - Req::OutPeers(r) => Resp::OutPeers(out_peers(state, r)?), - Req::InPeers(r) => Resp::InPeers(in_peers(state, r)?), - Req::GetNetStats(r) => Resp::GetNetStats(get_net_stats(state, r)?), - Req::GetOuts(r) => Resp::GetOuts(get_outs(state, r)?), - Req::Update(r) => Resp::Update(update(state, r)?), - Req::PopBlocks(r) => Resp::PopBlocks(pop_blocks(state, r)?), + 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)?) + Resp::GetTransactionPoolHashes(get_transaction_pool_hashes(state, r).await?) } - Req::GetPublicNodes(r) => Resp::GetPublicNodes(get_public_nodes(state, r)?), + Req::GetPublicNodes(r) => Resp::GetPublicNodes(get_public_nodes(state, r).await?), }) } -fn get_height( +async fn get_height( state: CupratedRpcHandler, request: GetHeightRequest, ) -> Result { todo!() } -fn get_transactions( +async fn get_transactions( state: CupratedRpcHandler, request: GetTransactionsRequest, ) -> Result { todo!() } -fn get_alt_blocks_hashes( +async fn get_alt_blocks_hashes( state: CupratedRpcHandler, request: GetAltBlocksHashesRequest, ) -> Result { todo!() } -fn is_key_image_spent( +async fn is_key_image_spent( state: CupratedRpcHandler, request: IsKeyImageSpentRequest, ) -> Result { todo!() } -fn send_raw_transaction( +async fn send_raw_transaction( state: CupratedRpcHandler, request: SendRawTransactionRequest, ) -> Result { todo!() } -fn start_mining( +async fn start_mining( state: CupratedRpcHandler, request: StartMiningRequest, ) -> Result { todo!() } -fn stop_mining( +async fn stop_mining( state: CupratedRpcHandler, request: StopMiningRequest, ) -> Result { todo!() } -fn mining_status( +async fn mining_status( state: CupratedRpcHandler, request: MiningStatusRequest, ) -> Result { todo!() } -fn save_bc(state: CupratedRpcHandler, request: SaveBcRequest) -> Result { +async fn save_bc( + state: CupratedRpcHandler, + request: SaveBcRequest, +) -> Result { todo!() } -fn get_peer_list( +async fn get_peer_list( state: CupratedRpcHandler, request: GetPeerListRequest, ) -> Result { todo!() } -fn set_log_hash_rate( +async fn set_log_hash_rate( state: CupratedRpcHandler, request: SetLogHashRateRequest, ) -> Result { todo!() } -fn set_log_level( +async fn set_log_level( state: CupratedRpcHandler, request: SetLogLevelRequest, ) -> Result { todo!() } -fn set_log_categories( +async fn set_log_categories( state: CupratedRpcHandler, request: SetLogCategoriesRequest, ) -> Result { todo!() } -fn set_bootstrap_daemon( +async fn set_bootstrap_daemon( state: CupratedRpcHandler, request: SetBootstrapDaemonRequest, ) -> Result { todo!() } -fn get_transaction_pool( +async fn get_transaction_pool( state: CupratedRpcHandler, request: GetTransactionPoolRequest, ) -> Result { todo!() } -fn get_transaction_pool_stats( +async fn get_transaction_pool_stats( state: CupratedRpcHandler, request: GetTransactionPoolStatsRequest, ) -> Result { todo!() } -fn stop_daemon( +async fn stop_daemon( state: CupratedRpcHandler, request: StopDaemonRequest, ) -> Result { todo!() } -fn get_limit( +async fn get_limit( state: CupratedRpcHandler, request: GetLimitRequest, ) -> Result { todo!() } -fn set_limit( +async fn set_limit( state: CupratedRpcHandler, request: SetLimitRequest, ) -> Result { todo!() } -fn out_peers( +async fn out_peers( state: CupratedRpcHandler, request: OutPeersRequest, ) -> Result { todo!() } -fn in_peers( +async fn in_peers( state: CupratedRpcHandler, request: InPeersRequest, ) -> Result { todo!() } -fn get_net_stats( +async fn get_net_stats( state: CupratedRpcHandler, request: GetNetStatsRequest, ) -> Result { todo!() } -fn get_outs( +async fn get_outs( state: CupratedRpcHandler, request: GetOutsRequest, ) -> Result { todo!() } -fn update(state: CupratedRpcHandler, request: UpdateRequest) -> Result { +async fn update( + state: CupratedRpcHandler, + request: UpdateRequest, +) -> Result { todo!() } -fn pop_blocks( +async fn pop_blocks( state: CupratedRpcHandler, request: PopBlocksRequest, ) -> Result { todo!() } -fn get_transaction_pool_hashes( +async fn get_transaction_pool_hashes( state: CupratedRpcHandler, request: GetTransactionPoolHashesRequest, ) -> Result { todo!() } -fn get_public_nodes( +async fn get_public_nodes( state: CupratedRpcHandler, request: GetPublicNodesRequest, ) -> Result { From d268c502467973ecc51b358393316cc629a6273e Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 5 Sep 2024 18:06:22 -0400 Subject: [PATCH 14/20] rpc/interface: impl `thiserror::Error` --- Cargo.lock | 2 ++ rpc/interface/Cargo.toml | 6 ++++-- rpc/interface/README.md | 6 +++--- rpc/interface/src/rpc_error.rs | 29 ++++++++++++++++++++++++----- rpc/interface/src/rpc_service.rs | 4 ++-- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d78d1fa09..426fced1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -800,6 +800,7 @@ name = "cuprate-rpc-interface" version = "0.0.0" dependencies = [ "axum", + "cuprate-database", "cuprate-epee-encoding", "cuprate-helper", "cuprate-json-rpc", @@ -809,6 +810,7 @@ dependencies = [ "paste", "serde", "serde_json", + "thiserror", "tokio", "tower", "ureq", diff --git a/rpc/interface/Cargo.toml b/rpc/interface/Cargo.toml index 5f173177c..56f3fd49c 100644 --- a/rpc/interface/Cargo.toml +++ b/rpc/interface/Cargo.toml @@ -9,18 +9,20 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/rpc/cuprate-rpc-inte keywords = ["cuprate", "rpc", "interface"] [features] -default = ["dummy", "serde"] -dummy = [] +default = ["dummy", "serde"] +dummy = [] [dependencies] cuprate-epee-encoding = { path = "../../net/epee-encoding", default-features = false } cuprate-json-rpc = { path = "../json-rpc", default-features = false } cuprate-rpc-types = { path = "../types", features = ["serde", "epee"], default-features = false } cuprate-helper = { path = "../../helper", features = ["asynch"], default-features = false } +cuprate-database = { path = "../../storage/database" } axum = { version = "0.7.5", features = ["json"], default-features = false } serde = { workspace = true, optional = true } tower = { workspace = true } +thiserror = { workspace = true } paste = { workspace = true } futures = { workspace = true } diff --git a/rpc/interface/README.md b/rpc/interface/README.md index e8be2d0da..eb8786435 100644 --- a/rpc/interface/README.md +++ b/rpc/interface/README.md @@ -33,7 +33,7 @@ This crate simply handles: - Defining handler function signatures - (De)serialization of requests/responses (JSON-RPC, binary, JSON) -The actual server details are all handled by the [`axum`] and [`tower`] ecosystem.a +The actual server details are all handled by the [`axum`] and [`tower`] ecosystem. The proper usage of this crate is to: 1. Implement a [`RpcHandler`] @@ -45,8 +45,8 @@ The proper usage of this crate is to: This is your [`tower::Service`] that converts `Request`s into `Response`s, i.e. the "inner handler". -Said concretely, `RpcHandler` is 3 `tower::Service`s where the associated types are -the 3 endpoint enums from [`cuprate_rpc_types`] and the error type from this crate: +Said concretely, `RpcHandler` is 3 `tower::Service`s where the request/response types are +the 3 endpoint enums from [`cuprate_rpc_types`] and the error type is from this crate: - [`JsonRpcRequest`](cuprate_rpc_types::json::JsonRpcRequest) & [`JsonRpcResponse`](cuprate_rpc_types::json::JsonRpcResponse) - [`BinRequest`](cuprate_rpc_types::bin::BinRequest) & [`BinResponse`](cuprate_rpc_types::bin::BinRequest) - [`OtherRequest`](cuprate_rpc_types::other::OtherRequest) & [`OtherResponse`](cuprate_rpc_types::other::OtherRequest) diff --git a/rpc/interface/src/rpc_error.rs b/rpc/interface/src/rpc_error.rs index 47563d65a..59f371ab6 100644 --- a/rpc/interface/src/rpc_error.rs +++ b/rpc/interface/src/rpc_error.rs @@ -2,8 +2,8 @@ //---------------------------------------------------------------------------------------------------- Import use axum::http::StatusCode; -#[cfg(feature = "serde")] -use serde::{Deserialize, Serialize}; + +use cuprate_database::RuntimeError; //---------------------------------------------------------------------------------------------------- RpcError /// Possible errors during RPC operation. @@ -16,9 +16,16 @@ use serde::{Deserialize, Serialize}; /// /// 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 {} +#[derive(Debug, thiserror::Error)] +pub enum RpcError { + /// A [`std::io::Error`] from the database. + #[error("database I/O error: {0}")] + DatabaseIo(#[from] std::io::Error), + + /// A (non-I/O related) database error. + #[error("database error: {0}")] + DatabaseError(RuntimeError), +} impl From for StatusCode { fn from(_: RpcError) -> Self { @@ -27,6 +34,18 @@ impl From for StatusCode { } } +impl From for RpcError { + fn from(error: RuntimeError) -> Self { + match error { + RuntimeError::Io(io) => Self::DatabaseIo(io), + RuntimeError::KeyExists + | RuntimeError::KeyNotFound + | RuntimeError::ResizeNeeded + | RuntimeError::TableNotFound => Self::DatabaseError(error), + } + } +} + //---------------------------------------------------------------------------------------------------- Tests #[cfg(test)] mod test { diff --git a/rpc/interface/src/rpc_service.rs b/rpc/interface/src/rpc_service.rs index db8483074..b85ac047f 100644 --- a/rpc/interface/src/rpc_service.rs +++ b/rpc/interface/src/rpc_service.rs @@ -32,7 +32,7 @@ pub trait RpcService: Request, Response = Response, Error = RpcError, - Future: Future> + Send + Sync + 'static, + Future: Future> + Send + 'static, > { } @@ -46,7 +46,7 @@ impl RpcService for T where Request, Response = Response, Error = RpcError, - Future: Future> + Send + Sync + 'static, + Future: Future> + Send + 'static, > { } From d443cfb9b74a91f3719bbc827c11199039d05d47 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 5 Sep 2024 18:11:27 -0400 Subject: [PATCH 15/20] split state from main handler struct --- binaries/cuprated/src/rpc.rs | 2 +- binaries/cuprated/src/rpc/bin.rs | 18 ++++---- binaries/cuprated/src/rpc/handler.rs | 24 ++++++----- binaries/cuprated/src/rpc/json.rs | 64 ++++++++++++++-------------- binaries/cuprated/src/rpc/other.rs | 58 ++++++++++++------------- 5 files changed, 85 insertions(+), 81 deletions(-) diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 1b483a936..18ba53354 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -9,4 +9,4 @@ mod handler; mod json; mod other; -pub use handler::CupratedRpcHandler; +pub use handler::{CupratedRpcHandler, CupratedRpcHandlerState}; diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs index a429ad342..a4bbabbb3 100644 --- a/binaries/cuprated/src/rpc/bin.rs +++ b/binaries/cuprated/src/rpc/bin.rs @@ -9,11 +9,11 @@ use cuprate_rpc_types::{ json::{GetOutputDistributionRequest, GetOutputDistributionResponse}, }; -use crate::rpc::CupratedRpcHandler; +use crate::rpc::CupratedRpcHandlerState; /// Map a [`BinRequest`] to the function that will lead to a [`BinResponse`]. pub(super) async fn map_request( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: BinRequest, ) -> Result { use BinRequest as Req; @@ -35,49 +35,49 @@ pub(super) async fn map_request( } async fn get_blocks( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBlocksRequest, ) -> Result { todo!() } async fn get_blocks_by_height( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBlocksByHeightRequest, ) -> Result { todo!() } async fn get_hashes( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetHashesRequest, ) -> Result { todo!() } async fn get_output_indexes( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetOutputIndexesRequest, ) -> Result { todo!() } async fn get_outs( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetOutsRequest, ) -> Result { todo!() } async fn get_transaction_pool_hashes( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetTransactionPoolHashesRequest, ) -> Result { todo!() } async fn get_output_distribution( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetOutputDistributionRequest, ) -> Result { todo!() diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 2f5b35db5..ca64b950d 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -23,8 +23,19 @@ use crate::rpc::{bin, json, other}; #[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, @@ -38,13 +49,6 @@ impl RpcHandler for CupratedRpcHandler { } } -// INVARIANT: -// -// We don't need to check for `self.is_restricted()` -// here because `cuprate-rpc-interface` handles that. -// -// We can assume the request coming has the required permissions. - impl Service for CupratedRpcHandler { type Response = JsonRpcResponse; type Error = RpcError; @@ -55,7 +59,7 @@ impl Service for CupratedRpcHandler { } fn call(&mut self, request: JsonRpcRequest) -> Self::Future { - let state = Self::clone(self); + let state = CupratedRpcHandlerState::clone(&self.state); Box::pin(json::map_request(state, request)) } } @@ -70,7 +74,7 @@ impl Service for CupratedRpcHandler { } fn call(&mut self, request: BinRequest) -> Self::Future { - let state = Self::clone(self); + let state = CupratedRpcHandlerState::clone(&self.state); Box::pin(bin::map_request(state, request)) } } @@ -85,7 +89,7 @@ impl Service for CupratedRpcHandler { } fn call(&mut self, request: OtherRequest) -> Self::Future { - let state = Self::clone(self); + let state = CupratedRpcHandlerState::clone(&self.state); Box::pin(other::map_request(state, request)) } } diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index 95bc94b3e..fdb293fc3 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -22,11 +22,11 @@ use cuprate_rpc_types::json::{ }; use tower::ServiceExt; -use crate::rpc::CupratedRpcHandler; +use crate::rpc::CupratedRpcHandlerState; /// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`]. pub(super) async fn map_request( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: JsonRpcRequest, ) -> Result { use JsonRpcRequest as Req; @@ -83,210 +83,210 @@ pub(super) async fn map_request( } async fn get_block_count( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBlockCountRequest, ) -> Result { todo!() } async fn on_get_block_hash( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: OnGetBlockHashRequest, ) -> Result { todo!() } async fn submit_block( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SubmitBlockRequest, ) -> Result { todo!() } async fn generate_blocks( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GenerateBlocksRequest, ) -> Result { todo!() } async fn get_last_block_header( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetLastBlockHeaderRequest, ) -> Result { todo!() } async fn get_block_header_by_hash( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBlockHeaderByHashRequest, ) -> Result { todo!() } async fn get_block_header_by_height( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBlockHeaderByHeightRequest, ) -> Result { todo!() } async fn get_block_headers_range( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBlockHeadersRangeRequest, ) -> Result { todo!() } async fn get_block( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBlockRequest, ) -> Result { todo!() } async fn get_connections( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetConnectionsRequest, ) -> Result { todo!() } async fn get_info( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetInfoRequest, ) -> Result { todo!() } async fn hard_fork_info( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: HardForkInfoRequest, ) -> Result { todo!() } async fn set_bans( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SetBansRequest, ) -> Result { todo!() } async fn get_bans( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetBansRequest, ) -> Result { todo!() } async fn banned( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: BannedRequest, ) -> Result { todo!() } async fn flush_transaction_pool( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: FlushTransactionPoolRequest, ) -> Result { todo!() } async fn get_output_histogram( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetOutputHistogramRequest, ) -> Result { todo!() } async fn get_coinbase_tx_sum( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetCoinbaseTxSumRequest, ) -> Result { todo!() } async fn get_version( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetVersionRequest, ) -> Result { todo!() } async fn get_fee_estimate( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetFeeEstimateRequest, ) -> Result { todo!() } async fn get_alternate_chains( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetAlternateChainsRequest, ) -> Result { todo!() } async fn relay_tx( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: RelayTxRequest, ) -> Result { todo!() } async fn sync_info( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SyncInfoRequest, ) -> Result { todo!() } async fn get_transaction_pool_backlog( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetTransactionPoolBacklogRequest, ) -> Result { todo!() } async fn get_miner_data( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetMinerDataRequest, ) -> Result { todo!() } async fn prune_blockchain( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: PruneBlockchainRequest, ) -> Result { todo!() } async fn calc_pow( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: CalcPowRequest, ) -> Result { todo!() } async fn flush_cache( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: FlushCacheRequest, ) -> Result { todo!() } async fn add_aux_pow( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: AddAuxPowRequest, ) -> Result { todo!() } async fn get_tx_ids_loose( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetTxIdsLooseRequest, ) -> Result { todo!() diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index c876e5425..b23ebdf94 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -16,11 +16,11 @@ use cuprate_rpc_types::other::{ StopDaemonResponse, StopMiningRequest, StopMiningResponse, UpdateRequest, UpdateResponse, }; -use crate::rpc::CupratedRpcHandler; +use crate::rpc::CupratedRpcHandlerState; /// Map a [`OtherRequest`] to the function that will lead to a [`OtherResponse`]. pub(super) async fn map_request( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: OtherRequest, ) -> Result { use OtherRequest as Req; @@ -70,189 +70,189 @@ pub(super) async fn map_request( } async fn get_height( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetHeightRequest, ) -> Result { todo!() } async fn get_transactions( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetTransactionsRequest, ) -> Result { todo!() } async fn get_alt_blocks_hashes( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetAltBlocksHashesRequest, ) -> Result { todo!() } async fn is_key_image_spent( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: IsKeyImageSpentRequest, ) -> Result { todo!() } async fn send_raw_transaction( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SendRawTransactionRequest, ) -> Result { todo!() } async fn start_mining( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: StartMiningRequest, ) -> Result { todo!() } async fn stop_mining( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: StopMiningRequest, ) -> Result { todo!() } async fn mining_status( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: MiningStatusRequest, ) -> Result { todo!() } async fn save_bc( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SaveBcRequest, ) -> Result { todo!() } async fn get_peer_list( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetPeerListRequest, ) -> Result { todo!() } async fn set_log_hash_rate( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SetLogHashRateRequest, ) -> Result { todo!() } async fn set_log_level( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SetLogLevelRequest, ) -> Result { todo!() } async fn set_log_categories( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SetLogCategoriesRequest, ) -> Result { todo!() } async fn set_bootstrap_daemon( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SetBootstrapDaemonRequest, ) -> Result { todo!() } async fn get_transaction_pool( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetTransactionPoolRequest, ) -> Result { todo!() } async fn get_transaction_pool_stats( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetTransactionPoolStatsRequest, ) -> Result { todo!() } async fn stop_daemon( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: StopDaemonRequest, ) -> Result { todo!() } async fn get_limit( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetLimitRequest, ) -> Result { todo!() } async fn set_limit( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: SetLimitRequest, ) -> Result { todo!() } async fn out_peers( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: OutPeersRequest, ) -> Result { todo!() } async fn in_peers( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: InPeersRequest, ) -> Result { todo!() } async fn get_net_stats( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetNetStatsRequest, ) -> Result { todo!() } async fn get_outs( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetOutsRequest, ) -> Result { todo!() } async fn update( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: UpdateRequest, ) -> Result { todo!() } async fn pop_blocks( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: PopBlocksRequest, ) -> Result { todo!() } async fn get_transaction_pool_hashes( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetTransactionPoolHashesRequest, ) -> Result { todo!() } async fn get_public_nodes( - state: CupratedRpcHandler, + state: CupratedRpcHandlerState, request: GetPublicNodesRequest, ) -> Result { todo!() From 9f8f2c7edf516769a672838736c23e00942fa6ef Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Thu, 5 Sep 2024 18:23:39 -0400 Subject: [PATCH 16/20] cleanup --- binaries/cuprated/src/rpc.rs | 2 -- binaries/cuprated/src/rpc/handler.rs | 15 +++++++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/binaries/cuprated/src/rpc.rs b/binaries/cuprated/src/rpc.rs index 18ba53354..9ebcd1b82 100644 --- a/binaries/cuprated/src/rpc.rs +++ b/binaries/cuprated/src/rpc.rs @@ -2,8 +2,6 @@ //! //! Will contain the code to initiate the RPC and a request handler. -// TODO: remove after impl. - mod bin; mod handler; mod json; diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index ca64b950d..7dbb27f96 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -1,6 +1,6 @@ //! Dummy implementation of [`RpcHandler`]. -use std::task::Poll; +use std::task::{Context, Poll}; use cuprate_rpc_types::{ bin::{BinRequest, BinResponse}, @@ -43,6 +43,13 @@ pub struct CupratedRpcHandlerState { pub txpool: TxpoolReadHandle, } +impl CupratedRpcHandler { + /// TODO + pub fn init() { + todo!() + } +} + impl RpcHandler for CupratedRpcHandler { fn restricted(&self) -> bool { self.restricted @@ -54,7 +61,7 @@ impl Service for CupratedRpcHandler { type Error = RpcError; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } @@ -69,7 +76,7 @@ impl Service for CupratedRpcHandler { type Error = RpcError; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } @@ -84,7 +91,7 @@ impl Service for CupratedRpcHandler { type Error = RpcError; type Future = BoxFuture<'static, Result>; - fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { + fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) } From 1b944359525d1acb29aa11e39c03464a451dba05 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 6 Sep 2024 16:54:28 -0400 Subject: [PATCH 17/20] fix imports --- binaries/cuprated/src/rpc/handler.rs | 10 +++++----- binaries/cuprated/src/rpc/json.rs | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 7dbb27f96..ab15ff6bd 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -2,11 +2,6 @@ use std::task::{Context, Poll}; -use cuprate_rpc_types::{ - bin::{BinRequest, BinResponse}, - json::{JsonRpcRequest, JsonRpcResponse}, - other::{OtherRequest, OtherResponse}, -}; use futures::{channel::oneshot::channel, future::BoxFuture}; use serde::{Deserialize, Serialize}; use tower::Service; @@ -15,6 +10,11 @@ use cuprate_blockchain::service::BlockchainReadHandle; use cuprate_helper::asynch::InfallibleOneshotReceiver; use cuprate_json_rpc::Id; use cuprate_rpc_interface::{RpcError, 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}; diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index fdb293fc3..ece925e80 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -1,5 +1,7 @@ use std::sync::Arc; +use tower::ServiceExt; + use cuprate_rpc_interface::RpcError; use cuprate_rpc_types::json::{ AddAuxPowRequest, AddAuxPowResponse, BannedRequest, BannedResponse, CalcPowRequest, @@ -20,7 +22,6 @@ use cuprate_rpc_types::json::{ RelayTxResponse, SetBansRequest, SetBansResponse, SubmitBlockRequest, SubmitBlockResponse, SyncInfoRequest, SyncInfoResponse, }; -use tower::ServiceExt; use crate::rpc::CupratedRpcHandlerState; From 7e4015a38180f8f3dd172fd342d86e18f08b590d Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 6 Sep 2024 18:06:50 -0400 Subject: [PATCH 18/20] replace `RpcError` with `anyhow::Error` --- Cargo.lock | 1 - Cargo.toml | 1 + rpc/interface/Cargo.toml | 2 +- rpc/interface/README.md | 9 +++--- rpc/interface/src/lib.rs | 2 -- rpc/interface/src/rpc_error.rs | 53 -------------------------------- rpc/interface/src/rpc_handler.rs | 2 +- rpc/interface/src/rpc_service.rs | 12 +++----- 8 files changed, 13 insertions(+), 69 deletions(-) delete mode 100644 rpc/interface/src/rpc_error.rs diff --git a/Cargo.lock b/Cargo.lock index 426fced1d..3ca5d6afa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -800,7 +800,6 @@ name = "cuprate-rpc-interface" version = "0.0.0" dependencies = [ "axum", - "cuprate-database", "cuprate-epee-encoding", "cuprate-helper", "cuprate-json-rpc", diff --git a/Cargo.toml b/Cargo.toml index 8704cb788..2d7189366 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ opt-level = 1 opt-level = 3 [workspace.dependencies] +anyhow = { version = "1.0.87", default-features = false } async-trait = { version = "0.1.74", default-features = false } bitflags = { version = "2.4.2", default-features = false } borsh = { version = "1.2.1", default-features = false } diff --git a/rpc/interface/Cargo.toml b/rpc/interface/Cargo.toml index 56f3fd49c..feb1affbe 100644 --- a/rpc/interface/Cargo.toml +++ b/rpc/interface/Cargo.toml @@ -17,8 +17,8 @@ cuprate-epee-encoding = { path = "../../net/epee-encoding", default-features = f cuprate-json-rpc = { path = "../json-rpc", default-features = false } cuprate-rpc-types = { path = "../types", features = ["serde", "epee"], default-features = false } cuprate-helper = { path = "../../helper", features = ["asynch"], default-features = false } -cuprate-database = { path = "../../storage/database" } +anyhow = { workspace = true } axum = { version = "0.7.5", features = ["json"], default-features = false } serde = { workspace = true, optional = true } tower = { workspace = true } diff --git a/rpc/interface/README.md b/rpc/interface/README.md index eb8786435..fa5496c10 100644 --- a/rpc/interface/README.md +++ b/rpc/interface/README.md @@ -45,15 +45,16 @@ The proper usage of this crate is to: This is your [`tower::Service`] that converts `Request`s into `Response`s, i.e. the "inner handler". -Said concretely, `RpcHandler` is 3 `tower::Service`s where the request/response types are -the 3 endpoint enums from [`cuprate_rpc_types`] and the error type is from this crate: +Said concretely, `RpcHandler` is 3 `tower::Service`s where the +request/response types are the 3 endpoint enums from [`cuprate_rpc_types`]: - [`JsonRpcRequest`](cuprate_rpc_types::json::JsonRpcRequest) & [`JsonRpcResponse`](cuprate_rpc_types::json::JsonRpcResponse) - [`BinRequest`](cuprate_rpc_types::bin::BinRequest) & [`BinResponse`](cuprate_rpc_types::bin::BinRequest) - [`OtherRequest`](cuprate_rpc_types::other::OtherRequest) & [`OtherResponse`](cuprate_rpc_types::other::OtherRequest) -- [`RpcError`] `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 for RPC server operation. diff --git a/rpc/interface/src/lib.rs b/rpc/interface/src/lib.rs index ebea49399..1f84738e2 100644 --- a/rpc/interface/src/lib.rs +++ b/rpc/interface/src/lib.rs @@ -3,14 +3,12 @@ mod route; mod router_builder; -mod rpc_error; mod rpc_handler; #[cfg(feature = "dummy")] mod rpc_handler_dummy; mod rpc_service; pub use router_builder::RouterBuilder; -pub use rpc_error::RpcError; pub use rpc_handler::RpcHandler; #[cfg(feature = "dummy")] pub use rpc_handler_dummy::RpcHandlerDummy; diff --git a/rpc/interface/src/rpc_error.rs b/rpc/interface/src/rpc_error.rs deleted file mode 100644 index 59f371ab6..000000000 --- a/rpc/interface/src/rpc_error.rs +++ /dev/null @@ -1,53 +0,0 @@ -//! RPC errors. - -//---------------------------------------------------------------------------------------------------- Import -use axum::http::StatusCode; - -use cuprate_database::RuntimeError; - -//---------------------------------------------------------------------------------------------------- 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(Debug, thiserror::Error)] -pub enum RpcError { - /// A [`std::io::Error`] from the database. - #[error("database I/O error: {0}")] - DatabaseIo(#[from] std::io::Error), - - /// A (non-I/O related) database error. - #[error("database error: {0}")] - DatabaseError(RuntimeError), -} - -impl From for StatusCode { - fn from(_: RpcError) -> Self { - // TODO - Self::INTERNAL_SERVER_ERROR - } -} - -impl From for RpcError { - fn from(error: RuntimeError) -> Self { - match error { - RuntimeError::Io(io) => Self::DatabaseIo(io), - RuntimeError::KeyExists - | RuntimeError::KeyNotFound - | RuntimeError::ResizeNeeded - | RuntimeError::TableNotFound => Self::DatabaseError(error), - } - } -} - -//---------------------------------------------------------------------------------------------------- Tests -#[cfg(test)] -mod test { - // use super::*; -} diff --git a/rpc/interface/src/rpc_handler.rs b/rpc/interface/src/rpc_handler.rs index 1299ec487..1d2676c76 100644 --- a/rpc/interface/src/rpc_handler.rs +++ b/rpc/interface/src/rpc_handler.rs @@ -22,7 +22,7 @@ use crate::RpcService; /// 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`]. /// -/// 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. /// diff --git a/rpc/interface/src/rpc_service.rs b/rpc/interface/src/rpc_service.rs index b85ac047f..285d60ba4 100644 --- a/rpc/interface/src/rpc_service.rs +++ b/rpc/interface/src/rpc_service.rs @@ -5,8 +5,6 @@ use std::future::Future; use tower::Service; -use crate::rpc_error::RpcError; - //---------------------------------------------------------------------------------------------------- RpcService /// An RPC [`tower::Service`]. /// @@ -17,7 +15,7 @@ use crate::rpc_error::RpcError; /// The `Request` and `Response` are generic and /// 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 /// trait on types that implement `tower::Service` correctly. @@ -31,8 +29,8 @@ pub trait RpcService: + Service< Request, Response = Response, - Error = RpcError, - Future: Future> + Send + 'static, + Error = anyhow::Error, + Future: Future> + Send + 'static, > { } @@ -45,8 +43,8 @@ impl RpcService for T where + Service< Request, Response = Response, - Error = RpcError, - Future: Future> + Send + 'static, + Error = anyhow::Error, + Future: Future> + Send + 'static, > { } From aac1a31bedffe2e795821935bc345b5060e2a10c Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 6 Sep 2024 20:09:21 -0400 Subject: [PATCH 19/20] interface: update error --- rpc/interface/Cargo.toml | 1 - rpc/interface/src/route/bin.rs | 19 +++++++++++++++++-- rpc/interface/src/route/json_rpc.rs | 4 +++- rpc/interface/src/route/other.rs | 4 +++- rpc/interface/src/rpc_handler_dummy.rs | 25 +++++++++++++------------ 5 files changed, 36 insertions(+), 17 deletions(-) diff --git a/rpc/interface/Cargo.toml b/rpc/interface/Cargo.toml index feb1affbe..42d10554e 100644 --- a/rpc/interface/Cargo.toml +++ b/rpc/interface/Cargo.toml @@ -22,7 +22,6 @@ anyhow = { workspace = true } axum = { version = "0.7.5", features = ["json"], default-features = false } serde = { workspace = true, optional = true } tower = { workspace = true } -thiserror = { workspace = true } paste = { workspace = true } futures = { workspace = true } diff --git a/rpc/interface/src/route/bin.rs b/rpc/interface/src/route/bin.rs index 45447caf7..90d06c8f8 100644 --- a/rpc/interface/src/route/bin.rs +++ b/rpc/interface/src/route/bin.rs @@ -5,7 +5,14 @@ use axum::{body::Bytes, extract::State, http::StatusCode}; use tower::ServiceExt; 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; @@ -66,8 +73,16 @@ macro_rules! generate_endpoints_inner { ($variant:ident, $handler:ident, $request:expr) => { paste::paste! { { + // Check if restricted. + if [<$variant Request>]::IS_RESTRICTED && $handler.restricted() { + // TODO: mimic `monerod` behavior. + return Err(StatusCode::FORBIDDEN); + } + // 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 { panic!("RPC handler returned incorrect response"); diff --git a/rpc/interface/src/route/json_rpc.rs b/rpc/interface/src/route/json_rpc.rs index bf3d937db..7efb85137 100644 --- a/rpc/interface/src/route/json_rpc.rs +++ b/rpc/interface/src/route/json_rpc.rs @@ -50,7 +50,9 @@ pub(crate) async fn json_rpc( } // 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))) } diff --git a/rpc/interface/src/route/other.rs b/rpc/interface/src/route/other.rs index 129ddd593..3ff84487e 100644 --- a/rpc/interface/src/route/other.rs +++ b/rpc/interface/src/route/other.rs @@ -82,7 +82,9 @@ macro_rules! generate_endpoints_inner { // Send 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 { panic!("RPC handler returned incorrect response") diff --git a/rpc/interface/src/rpc_handler_dummy.rs b/rpc/interface/src/rpc_handler_dummy.rs index 06fa4608b..0b0183546 100644 --- a/rpc/interface/src/rpc_handler_dummy.rs +++ b/rpc/interface/src/rpc_handler_dummy.rs @@ -3,19 +3,20 @@ //---------------------------------------------------------------------------------------------------- Use use std::task::Poll; -use cuprate_rpc_types::{ - bin::{BinRequest, BinResponse}, - json::{JsonRpcRequest, JsonRpcResponse}, - other::{OtherRequest, OtherResponse}, -}; +use anyhow::Error; use futures::channel::oneshot::channel; #[cfg(feature = "serde")] use serde::{Deserialize, Serialize}; use tower::Service; 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 /// An [`RpcHandler`] that always returns [`Default::default`]. @@ -45,8 +46,8 @@ impl RpcHandler for RpcHandlerDummy { impl Service for RpcHandlerDummy { type Response = JsonRpcResponse; - type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Error = Error; + type Future = InfallibleOneshotReceiver>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -100,8 +101,8 @@ impl Service for RpcHandlerDummy { impl Service for RpcHandlerDummy { type Response = BinResponse; - type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Error = Error; + type Future = InfallibleOneshotReceiver>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -130,8 +131,8 @@ impl Service for RpcHandlerDummy { impl Service for RpcHandlerDummy { type Response = OtherResponse; - type Error = RpcError; - type Future = InfallibleOneshotReceiver>; + type Error = Error; + type Future = InfallibleOneshotReceiver>; fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) From 6b16fb5688487f56af04c30419c374678cbe9b22 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Fri, 6 Sep 2024 20:09:42 -0400 Subject: [PATCH 20/20] cuprated: update error type --- Cargo.lock | 9 +++- binaries/cuprated/Cargo.toml | 1 + binaries/cuprated/src/rpc/bin.rs | 19 +++++---- binaries/cuprated/src/rpc/handler.rs | 15 ++++--- binaries/cuprated/src/rpc/json.rs | 64 ++++++++++++++-------------- binaries/cuprated/src/rpc/other.rs | 59 ++++++++++++------------- 6 files changed, 89 insertions(+), 78 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3ca5d6afa..0bb4612af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -56,6 +56,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "038dfcf04a5feb68e9c60b21c9625a54c2c0616e79b72b0fd87075a056ae1d1b" +[[package]] +name = "anyhow" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" + [[package]] name = "async-stream" version = "0.3.5" @@ -799,6 +805,7 @@ dependencies = [ name = "cuprate-rpc-interface" version = "0.0.0" dependencies = [ + "anyhow", "axum", "cuprate-epee-encoding", "cuprate-helper", @@ -809,7 +816,6 @@ dependencies = [ "paste", "serde", "serde_json", - "thiserror", "tokio", "tower", "ureq", @@ -910,6 +916,7 @@ dependencies = [ name = "cuprated" version = "0.1.0" dependencies = [ + "anyhow", "async-trait", "bitflags 2.5.0", "borsh", diff --git a/binaries/cuprated/Cargo.toml b/binaries/cuprated/Cargo.toml index 63a04317b..a886c124a 100644 --- a/binaries/cuprated/Cargo.toml +++ b/binaries/cuprated/Cargo.toml @@ -35,6 +35,7 @@ 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 } diff --git a/binaries/cuprated/src/rpc/bin.rs b/binaries/cuprated/src/rpc/bin.rs index a4bbabbb3..60d92c127 100644 --- a/binaries/cuprated/src/rpc/bin.rs +++ b/binaries/cuprated/src/rpc/bin.rs @@ -1,4 +1,5 @@ -use cuprate_rpc_interface::RpcError; +use anyhow::Error; + use cuprate_rpc_types::{ bin::{ BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksByHeightResponse, @@ -15,7 +16,7 @@ use crate::rpc::CupratedRpcHandlerState; pub(super) async fn map_request( state: CupratedRpcHandlerState, request: BinRequest, -) -> Result { +) -> Result { use BinRequest as Req; use BinResponse as Resp; @@ -37,48 +38,48 @@ pub(super) async fn map_request( async fn get_blocks( state: CupratedRpcHandlerState, request: GetBlocksRequest, -) -> Result { +) -> Result { todo!() } async fn get_blocks_by_height( state: CupratedRpcHandlerState, request: GetBlocksByHeightRequest, -) -> Result { +) -> Result { todo!() } async fn get_hashes( state: CupratedRpcHandlerState, request: GetHashesRequest, -) -> Result { +) -> Result { todo!() } async fn get_output_indexes( state: CupratedRpcHandlerState, request: GetOutputIndexesRequest, -) -> Result { +) -> Result { todo!() } async fn get_outs( state: CupratedRpcHandlerState, request: GetOutsRequest, -) -> Result { +) -> Result { todo!() } async fn get_transaction_pool_hashes( state: CupratedRpcHandlerState, request: GetTransactionPoolHashesRequest, -) -> Result { +) -> Result { todo!() } async fn get_output_distribution( state: CupratedRpcHandlerState, request: GetOutputDistributionRequest, -) -> Result { +) -> Result { todo!() } diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index ab15ff6bd..8ba25eab6 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -2,6 +2,7 @@ use std::task::{Context, Poll}; +use anyhow::Error; use futures::{channel::oneshot::channel, future::BoxFuture}; use serde::{Deserialize, Serialize}; use tower::Service; @@ -9,7 +10,7 @@ use tower::Service; use cuprate_blockchain::service::BlockchainReadHandle; use cuprate_helper::asynch::InfallibleOneshotReceiver; use cuprate_json_rpc::Id; -use cuprate_rpc_interface::{RpcError, RpcHandler}; +use cuprate_rpc_interface::RpcHandler; use cuprate_rpc_types::{ bin::{BinRequest, BinResponse}, json::{JsonRpcRequest, JsonRpcResponse}, @@ -58,8 +59,8 @@ impl RpcHandler for CupratedRpcHandler { impl Service for CupratedRpcHandler { type Response = JsonRpcResponse; - type Error = RpcError; - type Future = BoxFuture<'static, Result>; + type Error = Error; + type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -73,8 +74,8 @@ impl Service for CupratedRpcHandler { impl Service for CupratedRpcHandler { type Response = BinResponse; - type Error = RpcError; - type Future = BoxFuture<'static, Result>; + type Error = Error; + type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) @@ -88,8 +89,8 @@ impl Service for CupratedRpcHandler { impl Service for CupratedRpcHandler { type Response = OtherResponse; - type Error = RpcError; - type Future = BoxFuture<'static, Result>; + type Error = Error; + type Future = BoxFuture<'static, Result>; fn poll_ready(&mut self, _: &mut Context<'_>) -> Poll> { Poll::Ready(Ok(())) diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index ece925e80..41398d480 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -1,8 +1,8 @@ use std::sync::Arc; +use anyhow::Error; use tower::ServiceExt; -use cuprate_rpc_interface::RpcError; use cuprate_rpc_types::json::{ AddAuxPowRequest, AddAuxPowResponse, BannedRequest, BannedResponse, CalcPowRequest, CalcPowResponse, FlushCacheRequest, FlushCacheResponse, FlushTransactionPoolRequest, @@ -29,7 +29,7 @@ use crate::rpc::CupratedRpcHandlerState; pub(super) async fn map_request( state: CupratedRpcHandlerState, request: JsonRpcRequest, -) -> Result { +) -> Result { use JsonRpcRequest as Req; use JsonRpcResponse as Resp; @@ -86,209 +86,209 @@ pub(super) async fn map_request( async fn get_block_count( state: CupratedRpcHandlerState, request: GetBlockCountRequest, -) -> Result { +) -> Result { todo!() } async fn on_get_block_hash( state: CupratedRpcHandlerState, request: OnGetBlockHashRequest, -) -> Result { +) -> Result { todo!() } async fn submit_block( state: CupratedRpcHandlerState, request: SubmitBlockRequest, -) -> Result { +) -> Result { todo!() } async fn generate_blocks( state: CupratedRpcHandlerState, request: GenerateBlocksRequest, -) -> Result { +) -> Result { todo!() } async fn get_last_block_header( state: CupratedRpcHandlerState, request: GetLastBlockHeaderRequest, -) -> Result { +) -> Result { todo!() } async fn get_block_header_by_hash( state: CupratedRpcHandlerState, request: GetBlockHeaderByHashRequest, -) -> Result { +) -> Result { todo!() } async fn get_block_header_by_height( state: CupratedRpcHandlerState, request: GetBlockHeaderByHeightRequest, -) -> Result { +) -> Result { todo!() } async fn get_block_headers_range( state: CupratedRpcHandlerState, request: GetBlockHeadersRangeRequest, -) -> Result { +) -> Result { todo!() } async fn get_block( state: CupratedRpcHandlerState, request: GetBlockRequest, -) -> Result { +) -> Result { todo!() } async fn get_connections( state: CupratedRpcHandlerState, request: GetConnectionsRequest, -) -> Result { +) -> Result { todo!() } async fn get_info( state: CupratedRpcHandlerState, request: GetInfoRequest, -) -> Result { +) -> Result { todo!() } async fn hard_fork_info( state: CupratedRpcHandlerState, request: HardForkInfoRequest, -) -> Result { +) -> Result { todo!() } async fn set_bans( state: CupratedRpcHandlerState, request: SetBansRequest, -) -> Result { +) -> Result { todo!() } async fn get_bans( state: CupratedRpcHandlerState, request: GetBansRequest, -) -> Result { +) -> Result { todo!() } async fn banned( state: CupratedRpcHandlerState, request: BannedRequest, -) -> Result { +) -> Result { todo!() } async fn flush_transaction_pool( state: CupratedRpcHandlerState, request: FlushTransactionPoolRequest, -) -> Result { +) -> Result { todo!() } async fn get_output_histogram( state: CupratedRpcHandlerState, request: GetOutputHistogramRequest, -) -> Result { +) -> Result { todo!() } async fn get_coinbase_tx_sum( state: CupratedRpcHandlerState, request: GetCoinbaseTxSumRequest, -) -> Result { +) -> Result { todo!() } async fn get_version( state: CupratedRpcHandlerState, request: GetVersionRequest, -) -> Result { +) -> Result { todo!() } async fn get_fee_estimate( state: CupratedRpcHandlerState, request: GetFeeEstimateRequest, -) -> Result { +) -> Result { todo!() } async fn get_alternate_chains( state: CupratedRpcHandlerState, request: GetAlternateChainsRequest, -) -> Result { +) -> Result { todo!() } async fn relay_tx( state: CupratedRpcHandlerState, request: RelayTxRequest, -) -> Result { +) -> Result { todo!() } async fn sync_info( state: CupratedRpcHandlerState, request: SyncInfoRequest, -) -> Result { +) -> Result { todo!() } async fn get_transaction_pool_backlog( state: CupratedRpcHandlerState, request: GetTransactionPoolBacklogRequest, -) -> Result { +) -> Result { todo!() } async fn get_miner_data( state: CupratedRpcHandlerState, request: GetMinerDataRequest, -) -> Result { +) -> Result { todo!() } async fn prune_blockchain( state: CupratedRpcHandlerState, request: PruneBlockchainRequest, -) -> Result { +) -> Result { todo!() } async fn calc_pow( state: CupratedRpcHandlerState, request: CalcPowRequest, -) -> Result { +) -> Result { todo!() } async fn flush_cache( state: CupratedRpcHandlerState, request: FlushCacheRequest, -) -> Result { +) -> Result { todo!() } async fn add_aux_pow( state: CupratedRpcHandlerState, request: AddAuxPowRequest, -) -> Result { +) -> Result { todo!() } async fn get_tx_ids_loose( state: CupratedRpcHandlerState, request: GetTxIdsLooseRequest, -) -> Result { +) -> Result { todo!() } diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index b23ebdf94..c0df39931 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -1,4 +1,5 @@ -use cuprate_rpc_interface::RpcError; +use anyhow::Error; + use cuprate_rpc_types::other::{ GetAltBlocksHashesRequest, GetAltBlocksHashesResponse, GetHeightRequest, GetHeightResponse, GetLimitRequest, GetLimitResponse, GetNetStatsRequest, GetNetStatsResponse, GetOutsRequest, @@ -22,7 +23,7 @@ use crate::rpc::CupratedRpcHandlerState; pub(super) async fn map_request( state: CupratedRpcHandlerState, request: OtherRequest, -) -> Result { +) -> Result { use OtherRequest as Req; use OtherResponse as Resp; @@ -72,188 +73,188 @@ pub(super) async fn map_request( async fn get_height( state: CupratedRpcHandlerState, request: GetHeightRequest, -) -> Result { +) -> Result { todo!() } async fn get_transactions( state: CupratedRpcHandlerState, request: GetTransactionsRequest, -) -> Result { +) -> Result { todo!() } async fn get_alt_blocks_hashes( state: CupratedRpcHandlerState, request: GetAltBlocksHashesRequest, -) -> Result { +) -> Result { todo!() } async fn is_key_image_spent( state: CupratedRpcHandlerState, request: IsKeyImageSpentRequest, -) -> Result { +) -> Result { todo!() } async fn send_raw_transaction( state: CupratedRpcHandlerState, request: SendRawTransactionRequest, -) -> Result { +) -> Result { todo!() } async fn start_mining( state: CupratedRpcHandlerState, request: StartMiningRequest, -) -> Result { +) -> Result { todo!() } async fn stop_mining( state: CupratedRpcHandlerState, request: StopMiningRequest, -) -> Result { +) -> Result { todo!() } async fn mining_status( state: CupratedRpcHandlerState, request: MiningStatusRequest, -) -> Result { +) -> Result { todo!() } async fn save_bc( state: CupratedRpcHandlerState, request: SaveBcRequest, -) -> Result { +) -> Result { todo!() } async fn get_peer_list( state: CupratedRpcHandlerState, request: GetPeerListRequest, -) -> Result { +) -> Result { todo!() } async fn set_log_hash_rate( state: CupratedRpcHandlerState, request: SetLogHashRateRequest, -) -> Result { +) -> Result { todo!() } async fn set_log_level( state: CupratedRpcHandlerState, request: SetLogLevelRequest, -) -> Result { +) -> Result { todo!() } async fn set_log_categories( state: CupratedRpcHandlerState, request: SetLogCategoriesRequest, -) -> Result { +) -> Result { todo!() } async fn set_bootstrap_daemon( state: CupratedRpcHandlerState, request: SetBootstrapDaemonRequest, -) -> Result { +) -> Result { todo!() } async fn get_transaction_pool( state: CupratedRpcHandlerState, request: GetTransactionPoolRequest, -) -> Result { +) -> Result { todo!() } async fn get_transaction_pool_stats( state: CupratedRpcHandlerState, request: GetTransactionPoolStatsRequest, -) -> Result { +) -> Result { todo!() } async fn stop_daemon( state: CupratedRpcHandlerState, request: StopDaemonRequest, -) -> Result { +) -> Result { todo!() } async fn get_limit( state: CupratedRpcHandlerState, request: GetLimitRequest, -) -> Result { +) -> Result { todo!() } async fn set_limit( state: CupratedRpcHandlerState, request: SetLimitRequest, -) -> Result { +) -> Result { todo!() } async fn out_peers( state: CupratedRpcHandlerState, request: OutPeersRequest, -) -> Result { +) -> Result { todo!() } async fn in_peers( state: CupratedRpcHandlerState, request: InPeersRequest, -) -> Result { +) -> Result { todo!() } async fn get_net_stats( state: CupratedRpcHandlerState, request: GetNetStatsRequest, -) -> Result { +) -> Result { todo!() } async fn get_outs( state: CupratedRpcHandlerState, request: GetOutsRequest, -) -> Result { +) -> Result { todo!() } async fn update( state: CupratedRpcHandlerState, request: UpdateRequest, -) -> Result { +) -> Result { todo!() } async fn pop_blocks( state: CupratedRpcHandlerState, request: PopBlocksRequest, -) -> Result { +) -> Result { todo!() } async fn get_transaction_pool_hashes( state: CupratedRpcHandlerState, request: GetTransactionPoolHashesRequest, -) -> Result { +) -> Result { todo!() } async fn get_public_nodes( state: CupratedRpcHandlerState, request: GetPublicNodesRequest, -) -> Result { +) -> Result { todo!() }