cuprated/rpc/handlers/
shared.rs
1use std::{
8 collections::{HashMap, HashSet},
9 num::NonZero,
10};
11
12use anyhow::{anyhow, Error};
13use cuprate_types::OutputDistributionInput;
14use monero_serai::transaction::Timelock;
15
16use cuprate_constants::rpc::MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT;
17use cuprate_helper::cast::usize_to_u64;
18use cuprate_hex::Hex;
19use cuprate_rpc_interface::RpcHandler;
20use cuprate_rpc_types::{
21 bin::{
22 GetOutsRequest, GetOutsResponse, GetTransactionPoolHashesRequest,
23 GetTransactionPoolHashesResponse,
24 },
25 json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
26 misc::{Distribution, OutKeyBin},
27};
28
29use crate::rpc::{
30 handlers::helper,
31 service::{blockchain, blockchain_context, txpool},
32 CupratedRpcHandler,
33};
34
35pub(super) async fn get_outs(
41 mut state: CupratedRpcHandler,
42 request: GetOutsRequest,
43) -> Result<GetOutsResponse, Error> {
44 if state.is_restricted() && request.outputs.len() > MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT {
45 return Err(anyhow!("Too many outs requested"));
46 }
47
48 let outputs = blockchain::outputs_vec(
49 &mut state.blockchain_read,
50 request.outputs,
51 request.get_txid,
52 )
53 .await?;
54 let mut outs = Vec::<OutKeyBin>::with_capacity(outputs.len());
55 let blockchain_ctx = state.blockchain_context.blockchain_context();
56
57 for (_, index_vec) in outputs {
58 for (_, out) in index_vec {
59 let out_key = OutKeyBin {
60 key: out.key.0,
61 mask: out.commitment.0,
62 unlocked: cuprate_consensus_rules::transactions::output_unlocked(
63 &out.time_lock,
64 blockchain_ctx.chain_height,
65 blockchain_ctx.current_adjusted_timestamp_for_time_lock(),
66 blockchain_ctx.current_hf,
67 ),
68 height: usize_to_u64(out.height),
69 txid: out.txid.unwrap_or_default(),
70 };
71
72 outs.push(out_key);
73 }
74 }
75
76 Ok(GetOutsResponse {
77 base: helper::access_response_base(false),
78 outs,
79 })
80}
81
82pub(super) async fn get_transaction_pool_hashes(
90 mut state: CupratedRpcHandler,
91) -> Result<Vec<[u8; 32]>, Error> {
92 let include_sensitive_txs = !state.is_restricted();
93 txpool::all_hashes(&mut state.txpool_read, include_sensitive_txs).await
94}
95
96pub(super) async fn get_output_distribution(
104 mut state: CupratedRpcHandler,
105 request: GetOutputDistributionRequest,
106) -> Result<GetOutputDistributionResponse, Error> {
107 if state.is_restricted() && request.amounts != [0] {
108 return Err(anyhow!(
109 "Restricted RPC can only get output distribution for RCT outputs. Use your own node."
110 ));
111 }
112
113 let input = OutputDistributionInput {
114 amounts: request.amounts,
115 cumulative: request.cumulative,
116 from_height: request.from_height,
117
118 to_height: NonZero::new(request.to_height),
120 };
121
122 let distributions = blockchain::output_distribution(&mut state.blockchain_read, input).await?;
123
124 Ok(GetOutputDistributionResponse {
125 base: helper::access_response_base(false),
126 distributions: todo!(
127 "This type contains binary strings: <https://github.com/monero-project/monero/issues/9422>"
128 ),
129 })
130}