cuprate_rpc_interface/route/
bin.rs
1use axum::{body::Bytes, extract::State, http::StatusCode};
5use tower::ServiceExt;
6
7use cuprate_epee_encoding::from_bytes;
8use cuprate_rpc_types::{
9 bin::{
10 BinRequest, BinResponse, GetBlocksByHeightRequest, GetBlocksRequest, GetHashesRequest,
11 GetOutputIndexesRequest, GetOutsRequest, GetTransactionPoolHashesRequest,
12 },
13 json::GetOutputDistributionRequest,
14 RpcCall,
15};
16
17use crate::rpc_handler::RpcHandler;
18
19macro_rules! generate_endpoints_with_input {
24 ($(
25 $endpoint:ident => $variant:ident
28 ),*) => { paste::paste! {
29 $(
30 pub(crate) async fn $endpoint<H: RpcHandler>(
32 State(handler): State<H>,
33 mut request: Bytes,
34 ) -> Result<Bytes, StatusCode> {
35 let request = BinRequest::$variant(
37 from_bytes(&mut request).map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?
38 );
39
40 generate_endpoints_inner!($variant, handler, request)
41 }
42 )*
43 }};
44}
45
46macro_rules! generate_endpoints_with_no_input {
50 ($(
51 $endpoint:ident => $variant:ident
54 ),*) => { paste::paste! {
55 $(
56 pub(crate) async fn $endpoint<H: RpcHandler>(
58 State(handler): State<H>,
59 ) -> Result<Bytes, StatusCode> {
60 const REQUEST: BinRequest = BinRequest::$variant([<$variant Request>] {});
61 generate_endpoints_inner!($variant, handler, REQUEST)
62 }
63 )*
64 }};
65}
66
67macro_rules! generate_endpoints_inner {
71 ($variant:ident, $handler:ident, $request:expr_2021) => {
72 paste::paste! {
73 {
74 if [<$variant Request>]::IS_RESTRICTED && $handler.is_restricted() {
82 return Err(StatusCode::FORBIDDEN);
84 }
85
86 let Ok(response) = $handler.oneshot($request).await else {
88 return Err(StatusCode::INTERNAL_SERVER_ERROR);
89 };
90
91 let BinResponse::$variant(response) = response else {
92 panic!("RPC handler returned incorrect response");
93 };
94
95 match cuprate_epee_encoding::to_bytes(response) {
97 Ok(bytes) => Ok(bytes.freeze()),
98 Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
99 }
100 }
101 }
102 };
103}
104
105generate_endpoints_with_input! {
106 get_blocks => GetBlocks,
107 get_blocks_by_height => GetBlocksByHeight,
108 get_hashes => GetHashes,
109 get_o_indexes => GetOutputIndexes,
110 get_outs => GetOuts,
111 get_output_distribution => GetOutputDistribution
112}
113
114generate_endpoints_with_no_input! {
115 get_transaction_pool_hashes => GetTransactionPoolHashes
116}
117
118#[cfg(test)]
120mod test {
121 }