Skip to main content

cuprate_rpc_interface/
rpc_handler_dummy.rs

1//! Dummy implementation of [`RpcHandler`].
2
3//---------------------------------------------------------------------------------------------------- Use
4use std::task::Poll;
5
6use anyhow::Error;
7use futures::channel::oneshot::channel;
8use serde::{Deserialize, Serialize};
9use tower::Service;
10
11use cuprate_helper::asynch::InfallibleOneshotReceiver;
12use cuprate_rpc_types::{
13    bin::{BinRequest, BinResponse},
14    json::{JsonRpcRequest, JsonRpcResponse},
15    other::{OtherRequest, OtherResponse},
16};
17
18use crate::rpc_handler::RpcHandler;
19
20//---------------------------------------------------------------------------------------------------- RpcHandlerDummy
21/// An [`RpcHandler`] that always returns [`Default::default`].
22///
23/// This `struct` implements [`RpcHandler`], and always responds
24/// with the response `struct` set to [`Default::default`].
25///
26/// See the [`crate`] documentation for example usage.
27///
28/// This is mostly used for testing purposes and can
29/// be disabled by disable the `dummy` feature flag.
30#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Serialize)]
31pub struct RpcHandlerDummy {
32    /// Should this RPC server be [restricted](RpcHandler::is_restricted)?
33    ///
34    /// The dummy will honor this [`bool`]
35    /// on restricted methods/endpoints.
36    pub restricted: bool,
37}
38
39impl RpcHandler for RpcHandlerDummy {
40    fn is_restricted(&self) -> bool {
41        self.restricted
42    }
43}
44
45impl Service<JsonRpcRequest> for RpcHandlerDummy {
46    type Response = JsonRpcResponse;
47    type Error = Error;
48    type Future = InfallibleOneshotReceiver<Result<JsonRpcResponse, Error>>;
49
50    fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
51        Poll::Ready(Ok(()))
52    }
53
54    fn call(&mut self, req: JsonRpcRequest) -> Self::Future {
55        use cuprate_rpc_types::json::JsonRpcRequest as Req;
56        use cuprate_rpc_types::json::JsonRpcResponse as Resp;
57
58        #[expect(clippy::default_trait_access)]
59        let resp = match req {
60            Req::GetBlockTemplate(_) => Resp::GetBlockTemplate(Default::default()),
61            Req::GetBlockCount(_) => Resp::GetBlockCount(Default::default()),
62            Req::OnGetBlockHash(_) => Resp::OnGetBlockHash(Default::default()),
63            Req::SubmitBlock(_) => Resp::SubmitBlock(Default::default()),
64            Req::GenerateBlocks(_) => Resp::GenerateBlocks(Default::default()),
65            Req::GetLastBlockHeader(_) => Resp::GetLastBlockHeader(Default::default()),
66            Req::GetBlockHeaderByHash(_) => Resp::GetBlockHeaderByHash(Default::default()),
67            Req::GetBlockHeaderByHeight(_) => Resp::GetBlockHeaderByHeight(Default::default()),
68            Req::GetBlockHeadersRange(_) => Resp::GetBlockHeadersRange(Default::default()),
69            Req::GetBlock(_) => Resp::GetBlock(Default::default()),
70            Req::GetConnections(_) => Resp::GetConnections(Default::default()),
71            Req::GetInfo(_) => Resp::GetInfo(Default::default()),
72            Req::HardForkInfo(_) => Resp::HardForkInfo(Default::default()),
73            Req::SetBans(_) => Resp::SetBans(Default::default()),
74            Req::GetBans(_) => Resp::GetBans(Default::default()),
75            Req::Banned(_) => Resp::Banned(Default::default()),
76            Req::FlushTxpool(_) => Resp::FlushTxpool(Default::default()),
77            Req::GetOutputHistogram(_) => Resp::GetOutputHistogram(Default::default()),
78            Req::GetCoinbaseTxSum(_) => Resp::GetCoinbaseTxSum(Default::default()),
79            Req::GetVersion(_) => Resp::GetVersion(Default::default()),
80            Req::GetFeeEstimate(_) => Resp::GetFeeEstimate(Default::default()),
81            Req::GetAlternateChains(_) => Resp::GetAlternateChains(Default::default()),
82            Req::RelayTx(_) => Resp::RelayTx(Default::default()),
83            Req::SyncInfo(_) => Resp::SyncInfo(Default::default()),
84            Req::GetTxpoolBacklog(_) => Resp::GetTxpoolBacklog(Default::default()),
85            Req::GetMinerData(_) => Resp::GetMinerData(Default::default()),
86            Req::PruneBlockchain(_) => Resp::PruneBlockchain(Default::default()),
87            Req::CalcPow(_) => Resp::CalcPow(Default::default()),
88            Req::FlushCache(_) => Resp::FlushCache(Default::default()),
89            Req::AddAuxPow(_) => Resp::AddAuxPow(Default::default()),
90            Req::GetTxIdsLoose(_) => Resp::GetTxIdsLoose(Default::default()),
91            Req::GetOutputDistribution(_) => Resp::GetOutputDistribution(Default::default()),
92        };
93
94        let (tx, rx) = channel();
95        drop(tx.send(Ok(resp)));
96        InfallibleOneshotReceiver::from(rx)
97    }
98}
99
100impl Service<BinRequest> for RpcHandlerDummy {
101    type Response = BinResponse;
102    type Error = Error;
103    type Future = InfallibleOneshotReceiver<Result<BinResponse, Error>>;
104
105    fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
106        Poll::Ready(Ok(()))
107    }
108
109    fn call(&mut self, req: BinRequest) -> Self::Future {
110        use cuprate_rpc_types::bin::BinRequest as Req;
111        use cuprate_rpc_types::bin::BinResponse as Resp;
112
113        #[expect(clippy::default_trait_access)]
114        let resp = match req {
115            Req::GetBlocks(_) => Resp::GetBlocks(Default::default()),
116            Req::GetBlocksByHeight(_) => Resp::GetBlocksByHeight(Default::default()),
117            Req::GetHashes(_) => Resp::GetHashes(Default::default()),
118            Req::GetOutputIndexes(_) => Resp::GetOutputIndexes(Default::default()),
119            Req::GetOuts(_) => Resp::GetOuts(Default::default()),
120            Req::GetTransactionPoolHashes(_) => Resp::GetTransactionPoolHashes(Default::default()),
121            Req::GetOutputDistribution(_) => Resp::GetOutputDistribution(Default::default()),
122        };
123
124        let (tx, rx) = channel();
125        drop(tx.send(Ok(resp)));
126        InfallibleOneshotReceiver::from(rx)
127    }
128}
129
130impl Service<OtherRequest> for RpcHandlerDummy {
131    type Response = OtherResponse;
132    type Error = Error;
133    type Future = InfallibleOneshotReceiver<Result<OtherResponse, Error>>;
134
135    fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
136        Poll::Ready(Ok(()))
137    }
138
139    fn call(&mut self, req: OtherRequest) -> Self::Future {
140        use cuprate_rpc_types::other::OtherRequest as Req;
141        use cuprate_rpc_types::other::OtherResponse as Resp;
142
143        #[expect(clippy::default_trait_access)]
144        let resp = match req {
145            Req::GetHeight(_) => Resp::GetHeight(Default::default()),
146            Req::GetTransactions(_) => Resp::GetTransactions(Default::default()),
147            Req::GetAltBlocksHashes(_) => Resp::GetAltBlocksHashes(Default::default()),
148            Req::IsKeyImageSpent(_) => Resp::IsKeyImageSpent(Default::default()),
149            Req::SendRawTransaction(_) => Resp::SendRawTransaction(Default::default()),
150            Req::StartMining(_) => Resp::StartMining(Default::default()),
151            Req::StopMining(_) => Resp::StopMining(Default::default()),
152            Req::MiningStatus(_) => Resp::MiningStatus(Default::default()),
153            Req::SaveBc(_) => Resp::SaveBc(Default::default()),
154            Req::GetPeerList(_) => Resp::GetPeerList(Default::default()),
155            Req::SetLogHashRate(_) => Resp::SetLogHashRate(Default::default()),
156            Req::SetLogLevel(_) => Resp::SetLogLevel(Default::default()),
157            Req::SetLogCategories(_) => Resp::SetLogCategories(Default::default()),
158            Req::SetBootstrapDaemon(_) => Resp::SetBootstrapDaemon(Default::default()),
159            Req::GetTransactionPool(_) => Resp::GetTransactionPool(Default::default()),
160            Req::GetTransactionPoolStats(_) => Resp::GetTransactionPoolStats(Default::default()),
161            Req::StopDaemon(_) => Resp::StopDaemon(Default::default()),
162            Req::GetLimit(_) => Resp::GetLimit(Default::default()),
163            Req::SetLimit(_) => Resp::SetLimit(Default::default()),
164            Req::OutPeers(_) => Resp::OutPeers(Default::default()),
165            Req::InPeers(_) => Resp::InPeers(Default::default()),
166            Req::GetNetStats(_) => Resp::GetNetStats(Default::default()),
167            Req::GetOuts(_) => Resp::GetOuts(Default::default()),
168            Req::Update(_) => Resp::Update(Default::default()),
169            Req::PopBlocks(_) => Resp::PopBlocks(Default::default()),
170            Req::GetTransactionPoolHashes(_) => Resp::GetTransactionPoolHashes(Default::default()),
171            Req::GetPublicNodes(_) => Resp::GetPublicNodes(Default::default()),
172            Req::GetInfo(_) => Resp::GetInfo(Default::default()),
173        };
174
175        let (tx, rx) = channel();
176        drop(tx.send(Ok(resp)));
177        InfallibleOneshotReceiver::from(rx)
178    }
179}