get_output_distribution

This commit is contained in:
hinto.janai 2024-11-15 15:51:06 -05:00
parent e975c420d9
commit d634bea297
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
8 changed files with 54 additions and 12 deletions

View file

@ -180,7 +180,7 @@ impl CupratedRpcHandler {
} }
impl RpcHandler for CupratedRpcHandler { impl RpcHandler for CupratedRpcHandler {
fn restricted(&self) -> bool { fn is_restricted(&self) -> bool {
self.restricted self.restricted
} }
} }

View file

@ -32,7 +32,8 @@ use cuprate_rpc_types::{
GetConnectionsRequest, GetConnectionsResponse, GetFeeEstimateRequest, GetConnectionsRequest, GetConnectionsResponse, GetFeeEstimateRequest,
GetFeeEstimateResponse, GetInfoRequest, GetInfoResponse, GetLastBlockHeaderRequest, GetFeeEstimateResponse, GetInfoRequest, GetInfoResponse, GetLastBlockHeaderRequest,
GetLastBlockHeaderResponse, GetMinerDataRequest, GetMinerDataResponse, GetLastBlockHeaderResponse, GetMinerDataRequest, GetMinerDataResponse,
GetOutputHistogramRequest, GetOutputHistogramResponse, GetTransactionPoolBacklogRequest, GetOutputDistributionRequest, GetOutputDistributionResponse, GetOutputHistogramRequest,
GetOutputHistogramResponse, GetTransactionPoolBacklogRequest,
GetTransactionPoolBacklogResponse, GetTxIdsLooseRequest, GetTxIdsLooseResponse, GetTransactionPoolBacklogResponse, GetTxIdsLooseRequest, GetTxIdsLooseResponse,
GetVersionRequest, GetVersionResponse, HardForkInfoRequest, HardForkInfoResponse, GetVersionRequest, GetVersionResponse, HardForkInfoRequest, HardForkInfoResponse,
JsonRpcRequest, JsonRpcResponse, OnGetBlockHashRequest, OnGetBlockHashResponse, JsonRpcRequest, JsonRpcResponse, OnGetBlockHashRequest, OnGetBlockHashResponse,
@ -41,8 +42,8 @@ use cuprate_rpc_types::{
SyncInfoResponse, SyncInfoResponse,
}, },
misc::{ misc::{
AuxPow, BlockHeader, ChainInfo, GetBan, GetMinerDataTxBacklogEntry, HardforkEntry, AuxPow, BlockHeader, ChainInfo, Distribution, GetBan, GetMinerDataTxBacklogEntry,
HistogramEntry, Status, SyncInfoPeer, TxBacklogEntry, HardforkEntry, HistogramEntry, Status, SyncInfoPeer, TxBacklogEntry,
}, },
CORE_RPC_VERSION, CORE_RPC_VERSION,
}; };
@ -109,6 +110,9 @@ pub(super) async fn map_request(
Req::GetTransactionPoolBacklog(r) => { Req::GetTransactionPoolBacklog(r) => {
Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r).await?) Resp::GetTransactionPoolBacklog(get_transaction_pool_backlog(state, r).await?)
} }
Req::GetOutputDistribution(r) => {
Resp::GetOutputDistribution(get_output_distribution(state, r).await?)
}
Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r).await?), Req::GetMinerData(r) => Resp::GetMinerData(get_miner_data(state, r).await?),
Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r).await?), Req::PruneBlockchain(r) => Resp::PruneBlockchain(prune_blockchain(state, r).await?),
Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r).await?), Req::CalcPow(r) => Resp::CalcPow(calc_pow(state, r).await?),
@ -217,7 +221,7 @@ async fn get_block_header_by_hash(
mut state: CupratedRpcHandler, mut state: CupratedRpcHandler,
request: GetBlockHeaderByHashRequest, request: GetBlockHeaderByHashRequest,
) -> Result<GetBlockHeaderByHashResponse, Error> { ) -> Result<GetBlockHeaderByHashResponse, Error> {
if state.restricted() && request.hashes.len() > RESTRICTED_BLOCK_COUNT { if state.is_restricted() && request.hashes.len() > RESTRICTED_BLOCK_COUNT {
return Err(anyhow!( return Err(anyhow!(
"Too many block headers requested in restricted mode" "Too many block headers requested in restricted mode"
)); ));
@ -282,7 +286,7 @@ async fn get_block_headers_range(
request.end_height.saturating_sub(request.start_height) + 1 > RESTRICTED_BLOCK_HEADER_RANGE request.end_height.saturating_sub(request.start_height) + 1 > RESTRICTED_BLOCK_HEADER_RANGE
}; };
if state.restricted() && too_many_blocks() { if state.is_restricted() && too_many_blocks() {
return Err(anyhow!("Too many block headers requested.")); return Err(anyhow!("Too many block headers requested."));
} }
@ -374,7 +378,7 @@ async fn get_info(
mut state: CupratedRpcHandler, mut state: CupratedRpcHandler,
request: GetInfoRequest, request: GetInfoRequest,
) -> Result<GetInfoResponse, Error> { ) -> Result<GetInfoResponse, Error> {
let restricted = state.restricted(); let restricted = state.is_restricted();
let context = blockchain_context::context(&mut state.blockchain_context).await?; let context = blockchain_context::context(&mut state.blockchain_context).await?;
let c = context.unchecked_blockchain_context(); let c = context.unchecked_blockchain_context();
@ -866,6 +870,39 @@ async fn get_transaction_pool_backlog(
}) })
} }
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L3352-L3398>
async fn get_output_distribution(
mut state: CupratedRpcHandler,
request: GetOutputDistributionRequest,
) -> Result<GetOutputDistributionResponse, Error> {
if state.is_restricted() && request.amounts != [1, 0] {
return Err(anyhow!(
"Restricted RPC can only get output distribution for RCT outputs. Use your own node."
));
}
// 0 is placeholder for the whole chain
let req_to_height = if request.to_height == 0 {
helper::top_height(&mut state).await?.0.saturating_sub(1)
} else {
request.to_height
};
let distributions = request.amounts.into_iter().map(|amount| {
fn get_output_distribution() -> Result<Distribution, Error> {
todo!("https://github.com/monero-project/monero/blob/893916ad091a92e765ce3241b94e706ad012b62a/src/rpc/rpc_handler.cpp#L29");
Err(anyhow!("Failed to get output distribution"))
}
get_output_distribution()
}).collect::<Result<Vec<Distribution>, _>>()?;
Ok(GetOutputDistributionResponse {
base: AccessResponseBase::OK,
distributions,
})
}
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L1998-L2033> /// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L1998-L2033>
async fn get_miner_data( async fn get_miner_data(
mut state: CupratedRpcHandler, mut state: CupratedRpcHandler,

View file

@ -72,7 +72,7 @@ macro_rules! generate_endpoints_inner {
paste::paste! { paste::paste! {
{ {
// Check if restricted. // Check if restricted.
if [<$variant Request>]::IS_RESTRICTED && $handler.restricted() { if [<$variant Request>]::IS_RESTRICTED && $handler.is_restricted() {
// TODO: mimic `monerod` behavior. // TODO: mimic `monerod` behavior.
return Err(StatusCode::FORBIDDEN); return Err(StatusCode::FORBIDDEN);
} }

View file

@ -37,7 +37,7 @@ pub(crate) async fn json_rpc<H: RpcHandler>(
// Return early if this RPC server is restricted and // Return early if this RPC server is restricted and
// the requested method is only for non-restricted RPC. // the requested method is only for non-restricted RPC.
if request.body.is_restricted() && handler.restricted() { if request.body.is_restricted() && handler.is_restricted() {
let error_object = ErrorObject { let error_object = ErrorObject {
code: ErrorCode::ServerError(-1 /* TODO */), code: ErrorCode::ServerError(-1 /* TODO */),
message: Cow::Borrowed("Restricted. TODO: mimic monerod message"), message: Cow::Borrowed("Restricted. TODO: mimic monerod message"),

View file

@ -75,7 +75,7 @@ macro_rules! generate_endpoints_inner {
paste::paste! { paste::paste! {
{ {
// Check if restricted. // Check if restricted.
if [<$variant Request>]::IS_RESTRICTED && $handler.restricted() { if [<$variant Request>]::IS_RESTRICTED && $handler.is_restricted() {
// TODO: mimic `monerod` behavior. // TODO: mimic `monerod` behavior.
return Err(StatusCode::FORBIDDEN); return Err(StatusCode::FORBIDDEN);
} }

View file

@ -46,5 +46,5 @@ pub trait RpcHandler:
/// ///
/// will automatically be denied access when using the /// will automatically be denied access when using the
/// [`axum::Router`] provided by [`RouterBuilder`](crate::RouterBuilder). /// [`axum::Router`] provided by [`RouterBuilder`](crate::RouterBuilder).
fn restricted(&self) -> bool; fn is_restricted(&self) -> bool;
} }

View file

@ -39,7 +39,7 @@ pub struct RpcHandlerDummy {
} }
impl RpcHandler for RpcHandlerDummy { impl RpcHandler for RpcHandlerDummy {
fn restricted(&self) -> bool { fn is_restricted(&self) -> bool {
self.restricted self.restricted
} }
} }
@ -85,6 +85,7 @@ impl Service<JsonRpcRequest> for RpcHandlerDummy {
Req::GetTransactionPoolBacklog(_) => { Req::GetTransactionPoolBacklog(_) => {
Resp::GetTransactionPoolBacklog(Default::default()) Resp::GetTransactionPoolBacklog(Default::default())
} }
Req::GetOutputDistribution(_) => Resp::GetOutputDistribution(Default::default()),
Req::GetMinerData(_) => Resp::GetMinerData(Default::default()), Req::GetMinerData(_) => Resp::GetMinerData(Default::default()),
Req::PruneBlockchain(_) => Resp::PruneBlockchain(Default::default()), Req::PruneBlockchain(_) => Resp::PruneBlockchain(Default::default()),
Req::CalcPow(_) => Resp::CalcPow(Default::default()), Req::CalcPow(_) => Resp::CalcPow(Default::default()),

View file

@ -1623,6 +1623,7 @@ pub enum JsonRpcRequest {
RelayTx(RelayTxRequest), RelayTx(RelayTxRequest),
SyncInfo(SyncInfoRequest), SyncInfo(SyncInfoRequest),
GetTransactionPoolBacklog(GetTransactionPoolBacklogRequest), GetTransactionPoolBacklog(GetTransactionPoolBacklogRequest),
GetOutputDistribution(GetOutputDistributionRequest),
GetMinerData(GetMinerDataRequest), GetMinerData(GetMinerDataRequest),
PruneBlockchain(PruneBlockchainRequest), PruneBlockchain(PruneBlockchainRequest),
CalcPow(CalcPowRequest), CalcPow(CalcPowRequest),
@ -1648,6 +1649,7 @@ impl RpcCallValue for JsonRpcRequest {
Self::GetVersion(x) => x.is_restricted(), Self::GetVersion(x) => x.is_restricted(),
Self::GetFeeEstimate(x) => x.is_restricted(), Self::GetFeeEstimate(x) => x.is_restricted(),
Self::GetTransactionPoolBacklog(x) => x.is_restricted(), Self::GetTransactionPoolBacklog(x) => x.is_restricted(),
Self::GetOutputDistribution(x) => x.is_restricted(),
Self::GetMinerData(x) => x.is_restricted(), Self::GetMinerData(x) => x.is_restricted(),
Self::AddAuxPow(x) => x.is_restricted(), Self::AddAuxPow(x) => x.is_restricted(),
Self::GetTxIdsLoose(x) => x.is_restricted(), Self::GetTxIdsLoose(x) => x.is_restricted(),
@ -1683,6 +1685,7 @@ impl RpcCallValue for JsonRpcRequest {
Self::GetVersion(x) => x.is_empty(), Self::GetVersion(x) => x.is_empty(),
Self::GetFeeEstimate(x) => x.is_empty(), Self::GetFeeEstimate(x) => x.is_empty(),
Self::GetTransactionPoolBacklog(x) => x.is_empty(), Self::GetTransactionPoolBacklog(x) => x.is_empty(),
Self::GetOutputDistribution(x) => x.is_empty(),
Self::GetMinerData(x) => x.is_empty(), Self::GetMinerData(x) => x.is_empty(),
Self::AddAuxPow(x) => x.is_empty(), Self::AddAuxPow(x) => x.is_empty(),
Self::GetTxIdsLoose(x) => x.is_empty(), Self::GetTxIdsLoose(x) => x.is_empty(),
@ -1755,6 +1758,7 @@ pub enum JsonRpcResponse {
RelayTx(RelayTxResponse), RelayTx(RelayTxResponse),
SyncInfo(SyncInfoResponse), SyncInfo(SyncInfoResponse),
GetTransactionPoolBacklog(GetTransactionPoolBacklogResponse), GetTransactionPoolBacklog(GetTransactionPoolBacklogResponse),
GetOutputDistribution(GetOutputDistributionResponse),
GetMinerData(GetMinerDataResponse), GetMinerData(GetMinerDataResponse),
PruneBlockchain(PruneBlockchainResponse), PruneBlockchain(PruneBlockchainResponse),
CalcPow(CalcPowResponse), CalcPow(CalcPowResponse),