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::is_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 is_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::GetBlockTemplate(_) => Resp::GetBlockTemplate(Default::default()),
63            Req::GetBlockCount(_) => Resp::GetBlockCount(Default::default()),
64            Req::OnGetBlockHash(_) => Resp::OnGetBlockHash(Default::default()),
65            Req::SubmitBlock(_) => Resp::SubmitBlock(Default::default()),
66            Req::GenerateBlocks(_) => Resp::GenerateBlocks(Default::default()),
67            Req::GetLastBlockHeader(_) => Resp::GetLastBlockHeader(Default::default()),
68            Req::GetBlockHeaderByHash(_) => Resp::GetBlockHeaderByHash(Default::default()),
69            Req::GetBlockHeaderByHeight(_) => Resp::GetBlockHeaderByHeight(Default::default()),
70            Req::GetBlockHeadersRange(_) => Resp::GetBlockHeadersRange(Default::default()),
71            Req::GetBlock(_) => Resp::GetBlock(Default::default()),
72            Req::GetConnections(_) => Resp::GetConnections(Default::default()),
73            Req::GetInfo(_) => Resp::GetInfo(Default::default()),
74            Req::HardForkInfo(_) => Resp::HardForkInfo(Default::default()),
75            Req::SetBans(_) => Resp::SetBans(Default::default()),
76            Req::GetBans(_) => Resp::GetBans(Default::default()),
77            Req::Banned(_) => Resp::Banned(Default::default()),
78            Req::FlushTransactionPool(_) => Resp::FlushTransactionPool(Default::default()),
79            Req::GetOutputHistogram(_) => Resp::GetOutputHistogram(Default::default()),
80            Req::GetCoinbaseTxSum(_) => Resp::GetCoinbaseTxSum(Default::default()),
81            Req::GetVersion(_) => Resp::GetVersion(Default::default()),
82            Req::GetFeeEstimate(_) => Resp::GetFeeEstimate(Default::default()),
83            Req::GetAlternateChains(_) => Resp::GetAlternateChains(Default::default()),
84            Req::RelayTx(_) => Resp::RelayTx(Default::default()),
85            Req::SyncInfo(_) => Resp::SyncInfo(Default::default()),
86            Req::GetTransactionPoolBacklog(_) => {
87                Resp::GetTransactionPoolBacklog(Default::default())
88            }
89            Req::GetMinerData(_) => Resp::GetMinerData(Default::default()),
90            Req::PruneBlockchain(_) => Resp::PruneBlockchain(Default::default()),
91            Req::CalcPow(_) => Resp::CalcPow(Default::default()),
92            Req::FlushCache(_) => Resp::FlushCache(Default::default()),
93            Req::AddAuxPow(_) => Resp::AddAuxPow(Default::default()),
94            Req::GetTxIdsLoose(_) => Resp::GetTxIdsLoose(Default::default()),
95        };
96
97        let (tx, rx) = channel();
98        drop(tx.send(Ok(resp)));
99        InfallibleOneshotReceiver::from(rx)
100    }
101}
102
103impl Service<BinRequest> for RpcHandlerDummy {
104    type Response = BinResponse;
105    type Error = Error;
106    type Future = InfallibleOneshotReceiver<Result<BinResponse, Error>>;
107
108    fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
109        Poll::Ready(Ok(()))
110    }
111
112    fn call(&mut self, req: BinRequest) -> Self::Future {
113        use cuprate_rpc_types::bin::BinRequest as Req;
114        use cuprate_rpc_types::bin::BinResponse as Resp;
115
116        #[expect(clippy::default_trait_access)]
117        let resp = match req {
118            Req::GetBlocks(_) => Resp::GetBlocks(Default::default()),
119            Req::GetBlocksByHeight(_) => Resp::GetBlocksByHeight(Default::default()),
120            Req::GetHashes(_) => Resp::GetHashes(Default::default()),
121            Req::GetOutputIndexes(_) => Resp::GetOutputIndexes(Default::default()),
122            Req::GetOuts(_) => Resp::GetOuts(Default::default()),
123            Req::GetTransactionPoolHashes(_) => Resp::GetTransactionPoolHashes(Default::default()),
124            Req::GetOutputDistribution(_) => Resp::GetOutputDistribution(Default::default()),
125        };
126
127        let (tx, rx) = channel();
128        drop(tx.send(Ok(resp)));
129        InfallibleOneshotReceiver::from(rx)
130    }
131}
132
133impl Service<OtherRequest> for RpcHandlerDummy {
134    type Response = OtherResponse;
135    type Error = Error;
136    type Future = InfallibleOneshotReceiver<Result<OtherResponse, Error>>;
137
138    fn poll_ready(&mut self, _: &mut std::task::Context<'_>) -> Poll<Result<(), Self::Error>> {
139        Poll::Ready(Ok(()))
140    }
141
142    fn call(&mut self, req: OtherRequest) -> Self::Future {
143        use cuprate_rpc_types::other::OtherRequest as Req;
144        use cuprate_rpc_types::other::OtherResponse as Resp;
145
146        #[expect(clippy::default_trait_access)]
147        let resp = match req {
148            Req::GetHeight(_) => Resp::GetHeight(Default::default()),
149            Req::GetTransactions(_) => Resp::GetTransactions(Default::default()),
150            Req::GetAltBlocksHashes(_) => Resp::GetAltBlocksHashes(Default::default()),
151            Req::IsKeyImageSpent(_) => Resp::IsKeyImageSpent(Default::default()),
152            Req::SendRawTransaction(_) => Resp::SendRawTransaction(Default::default()),
153            Req::StartMining(_) => Resp::StartMining(Default::default()),
154            Req::StopMining(_) => Resp::StopMining(Default::default()),
155            Req::MiningStatus(_) => Resp::MiningStatus(Default::default()),
156            Req::SaveBc(_) => Resp::SaveBc(Default::default()),
157            Req::GetPeerList(_) => Resp::GetPeerList(Default::default()),
158            Req::SetLogHashRate(_) => Resp::SetLogHashRate(Default::default()),
159            Req::SetLogLevel(_) => Resp::SetLogLevel(Default::default()),
160            Req::SetLogCategories(_) => Resp::SetLogCategories(Default::default()),
161            Req::SetBootstrapDaemon(_) => Resp::SetBootstrapDaemon(Default::default()),
162            Req::GetTransactionPool(_) => Resp::GetTransactionPool(Default::default()),
163            Req::GetTransactionPoolStats(_) => Resp::GetTransactionPoolStats(Default::default()),
164            Req::StopDaemon(_) => Resp::StopDaemon(Default::default()),
165            Req::GetLimit(_) => Resp::GetLimit(Default::default()),
166            Req::SetLimit(_) => Resp::SetLimit(Default::default()),
167            Req::OutPeers(_) => Resp::OutPeers(Default::default()),
168            Req::InPeers(_) => Resp::InPeers(Default::default()),
169            Req::GetNetStats(_) => Resp::GetNetStats(Default::default()),
170            Req::GetOuts(_) => Resp::GetOuts(Default::default()),
171            Req::Update(_) => Resp::Update(Default::default()),
172            Req::PopBlocks(_) => Resp::PopBlocks(Default::default()),
173            Req::GetTransactionPoolHashes(_) => Resp::GetTransactionPoolHashes(Default::default()),
174            Req::GetPublicNodes(_) => Resp::GetPublicNodes(Default::default()),
175        };
176
177        let (tx, rx) = channel();
178        drop(tx.send(Ok(resp)));
179        InfallibleOneshotReceiver::from(rx)
180    }
181}