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