mirror of
https://github.com/hinto-janai/cuprate.git
synced 2024-12-22 11:39:30 +00:00
Compare commits
3 commits
f7f9063890
...
ce6838bd6f
Author | SHA1 | Date | |
---|---|---|---|
|
ce6838bd6f | ||
|
3763dc9693 | ||
|
04cdc72f46 |
5 changed files with 101 additions and 54 deletions
|
@ -1,10 +1,13 @@
|
||||||
//! RPC request handler functions (binary endpoints).
|
//! RPC request handler functions (binary endpoints).
|
||||||
|
|
||||||
|
use std::num::NonZero;
|
||||||
|
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
|
|
||||||
use cuprate_constants::rpc::{RESTRICTED_BLOCK_COUNT, RESTRICTED_TRANSACTIONS_COUNT};
|
use cuprate_constants::rpc::{RESTRICTED_BLOCK_COUNT, RESTRICTED_TRANSACTIONS_COUNT};
|
||||||
use cuprate_fixed_bytes::ByteArrayVec;
|
use cuprate_fixed_bytes::ByteArrayVec;
|
||||||
|
use cuprate_helper::cast::{u64_to_usize, usize_to_u64};
|
||||||
use cuprate_rpc_interface::RpcHandler;
|
use cuprate_rpc_interface::RpcHandler;
|
||||||
use cuprate_rpc_types::{
|
use cuprate_rpc_types::{
|
||||||
base::{AccessResponseBase, ResponseBase},
|
base::{AccessResponseBase, ResponseBase},
|
||||||
|
@ -17,7 +20,10 @@ use cuprate_rpc_types::{
|
||||||
json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
|
json::{GetOutputDistributionRequest, GetOutputDistributionResponse},
|
||||||
misc::RequestedInfo,
|
misc::RequestedInfo,
|
||||||
};
|
};
|
||||||
use cuprate_types::{rpc::PoolInfoExtent, BlockCompleteEntry};
|
use cuprate_types::{
|
||||||
|
rpc::{PoolInfo, PoolInfoExtent},
|
||||||
|
BlockCompleteEntry,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::rpc::{
|
use crate::rpc::{
|
||||||
helper,
|
helper,
|
||||||
|
@ -50,7 +56,7 @@ pub(super) async fn map_request(
|
||||||
|
|
||||||
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L611-L789>
|
/// <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.cpp#L611-L789>
|
||||||
async fn get_blocks(
|
async fn get_blocks(
|
||||||
state: CupratedRpcHandler,
|
mut state: CupratedRpcHandler,
|
||||||
request: GetBlocksRequest,
|
request: GetBlocksRequest,
|
||||||
) -> Result<GetBlocksResponse, Error> {
|
) -> Result<GetBlocksResponse, Error> {
|
||||||
// Time should be set early:
|
// Time should be set early:
|
||||||
|
@ -58,7 +64,7 @@ async fn get_blocks(
|
||||||
let daemon_time = cuprate_helper::time::current_unix_timestamp();
|
let daemon_time = cuprate_helper::time::current_unix_timestamp();
|
||||||
|
|
||||||
let Some(requested_info) = RequestedInfo::from_u8(request.requested_info) else {
|
let Some(requested_info) = RequestedInfo::from_u8(request.requested_info) else {
|
||||||
return Err(anyhow!("Failed, wrong requested info"));
|
return Err(anyhow!("Wrong requested info"));
|
||||||
};
|
};
|
||||||
|
|
||||||
let (get_blocks, get_pool) = match requested_info {
|
let (get_blocks, get_pool) = match requested_info {
|
||||||
|
@ -69,60 +75,66 @@ async fn get_blocks(
|
||||||
|
|
||||||
let pool_info_extent = PoolInfoExtent::None;
|
let pool_info_extent = PoolInfoExtent::None;
|
||||||
|
|
||||||
if get_pool {
|
let pool_info = if get_pool {
|
||||||
let allow_sensitive = !state.is_restricted();
|
let include_sensitive_txs = !state.is_restricted();
|
||||||
let max_tx_count = if state.is_restricted() {
|
let max_tx_count = if state.is_restricted() {
|
||||||
RESTRICTED_TRANSACTIONS_COUNT
|
RESTRICTED_TRANSACTIONS_COUNT
|
||||||
} else {
|
} else {
|
||||||
usize::MAX
|
usize::MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
// bool incremental;
|
txpool::pool_info(
|
||||||
// std::vector<std::pair<crypto::hash, tx_memory_pool::tx_details>> added_pool_txs;
|
&mut state.txpool_read,
|
||||||
// bool success = m_core.get_pool_info((time_t)req.pool_info_since, allow_sensitive, max_tx_count, added_pool_txs, res.remaining_added_pool_txids, res.removed_pool_txids, incremental);
|
include_sensitive_txs,
|
||||||
// if (success)
|
max_tx_count,
|
||||||
// {
|
NonZero::new(u64_to_usize(request.pool_info_since)),
|
||||||
// res.added_pool_txs.clear();
|
)
|
||||||
// if (m_rpc_payment)
|
.await?
|
||||||
// {
|
} else {
|
||||||
// CHECK_PAYMENT_SAME_TS(req, res, added_pool_txs.size() * COST_PER_TX + (res.remaining_added_pool_txids.size() + res.removed_pool_txids.size()) * COST_PER_POOL_HASH);
|
PoolInfo::None
|
||||||
// }
|
};
|
||||||
// for (const auto &added_pool_tx: added_pool_txs)
|
|
||||||
// {
|
let resp = GetBlocksResponse {
|
||||||
// COMMAND_RPC_GET_BLOCKS_FAST::pool_tx_info info;
|
base: helper::access_response_base(false),
|
||||||
// info.tx_hash = added_pool_tx.first;
|
blocks: vec![],
|
||||||
// std::stringstream oss;
|
start_height: 0,
|
||||||
// binary_archive<true> ar(oss);
|
current_height: 0,
|
||||||
// bool r = req.prune
|
output_indices: vec![],
|
||||||
// ? const_cast<cryptonote::transaction&>(added_pool_tx.second.tx).serialize_base(ar)
|
daemon_time,
|
||||||
// : ::serialization::serialize(ar, const_cast<cryptonote::transaction&>(added_pool_tx.second.tx));
|
pool_info,
|
||||||
// if (!r)
|
};
|
||||||
// {
|
|
||||||
// res.status = "Failed to serialize transaction";
|
if !get_blocks {
|
||||||
// return true;
|
return Ok(resp);
|
||||||
// }
|
|
||||||
// info.tx_blob = oss.str();
|
|
||||||
// info.double_spend_seen = added_pool_tx.second.double_spend_seen;
|
|
||||||
// res.added_pool_txs.push_back(std::move(info));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if get_blocks {
|
// FIXME: impl `first()`
|
||||||
if !request.block_ids.is_empty() {
|
if !request.block_ids.is_empty() {
|
||||||
todo!();
|
let block_id = request.block_ids[0];
|
||||||
}
|
|
||||||
|
|
||||||
todo!();
|
let (height, hash) = helper::top_height(&mut state).await?;
|
||||||
|
|
||||||
|
if hash == block_id {
|
||||||
|
return Ok(GetBlocksResponse {
|
||||||
|
current_height: height + 1,
|
||||||
|
..resp
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let block_hashes: Vec<[u8; 32]> = (&request.block_ids).into();
|
||||||
|
|
||||||
|
let (blocks, missing_hashes, blockchain_height) =
|
||||||
|
blockchain::block_complete_entries(&mut state.blockchain_read, block_hashes).await?;
|
||||||
|
|
||||||
|
if !missing_hashes.is_empty() {
|
||||||
|
return Err(anyhow!("Missing blocks"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(GetBlocksResponse {
|
Ok(GetBlocksResponse {
|
||||||
base: helper::access_response_base(false),
|
blocks,
|
||||||
blocks: todo!(),
|
current_height: usize_to_u64(blockchain_height),
|
||||||
start_height: todo!(),
|
..resp
|
||||||
current_height: todo!(),
|
|
||||||
output_indices: todo!(),
|
|
||||||
daemon_time: todo!(),
|
|
||||||
pool_info: todo!(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -411,6 +411,27 @@ pub(crate) async fn total_rct_outputs(
|
||||||
Ok(n)
|
Ok(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// [`BlockchainReadRequest::BlockCompleteEntries`].
|
||||||
|
pub(crate) async fn block_complete_entries(
|
||||||
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
|
block_hashes: Vec<[u8; 32]>,
|
||||||
|
) -> Result<(Vec<BlockCompleteEntry>, Vec<[u8; 32]>, usize), Error> {
|
||||||
|
let BlockchainResponse::BlockCompleteEntries {
|
||||||
|
blocks,
|
||||||
|
missing_hashes,
|
||||||
|
blockchain_height,
|
||||||
|
} = blockchain_read
|
||||||
|
.ready()
|
||||||
|
.await?
|
||||||
|
.call(BlockchainReadRequest::BlockCompleteEntries(block_hashes))
|
||||||
|
.await?
|
||||||
|
else {
|
||||||
|
unreachable!();
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok((blocks, missing_hashes, blockchain_height))
|
||||||
|
}
|
||||||
|
|
||||||
/// [`BlockchainReadRequest::BlockCompleteEntriesByHeight`].
|
/// [`BlockchainReadRequest::BlockCompleteEntriesByHeight`].
|
||||||
pub(crate) async fn block_complete_entries_by_height(
|
pub(crate) async fn block_complete_entries_by_height(
|
||||||
blockchain_read: &mut BlockchainReadHandle,
|
blockchain_read: &mut BlockchainReadHandle,
|
||||||
|
|
|
@ -72,6 +72,12 @@ macro_rules! generate_endpoints_inner {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
{
|
{
|
||||||
// Check if restricted.
|
// Check if restricted.
|
||||||
|
//
|
||||||
|
// INVARIANT:
|
||||||
|
// The RPC handler functions in `cuprated` depend on this line existing,
|
||||||
|
// the functions themselves do not check if they are being called
|
||||||
|
// from an (un)restricted context. This line must be here or all
|
||||||
|
// methods will be allowed to be called freely.
|
||||||
if [<$variant Request>]::IS_RESTRICTED && $handler.is_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);
|
||||||
|
|
|
@ -37,16 +37,18 @@ 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.
|
||||||
|
//
|
||||||
|
// INVARIANT:
|
||||||
|
// The RPC handler functions in `cuprated` depend on this line existing,
|
||||||
|
// the functions themselves do not check if they are being called
|
||||||
|
// from an (un)restricted context. This line must be here or all
|
||||||
|
// methods will be allowed to be called freely.
|
||||||
if request.body.is_restricted() && handler.is_restricted() {
|
if request.body.is_restricted() && handler.is_restricted() {
|
||||||
let error_object = ErrorObject {
|
// The error when a restricted JSON-RPC method is called as per:
|
||||||
code: ErrorCode::ServerError(-1 /* TODO */),
|
//
|
||||||
message: Cow::Borrowed("Restricted. TODO: mimic monerod message"),
|
// - <https://github.com/monero-project/monero/blob/893916ad091a92e765ce3241b94e706ad012b62a/contrib/epee/include/net/http_server_handlers_map2.h#L244-L252>
|
||||||
data: None,
|
// - <https://github.com/monero-project/monero/blob/cc73fe71162d564ffda8e549b79a350bca53c454/src/rpc/core_rpc_server.h#L188>
|
||||||
};
|
return Ok(Json(Response::method_not_found(id)));
|
||||||
|
|
||||||
let response = Response::err(id, error_object);
|
|
||||||
|
|
||||||
return Ok(Json(response));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send request.
|
// Send request.
|
||||||
|
|
|
@ -75,6 +75,12 @@ macro_rules! generate_endpoints_inner {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
{
|
{
|
||||||
// Check if restricted.
|
// Check if restricted.
|
||||||
|
//
|
||||||
|
// INVARIANT:
|
||||||
|
// The RPC handler functions in `cuprated` depend on this line existing,
|
||||||
|
// the functions themselves do not check if they are being called
|
||||||
|
// from an (un)restricted context. This line must be here or all
|
||||||
|
// methods will be allowed to be called freely.
|
||||||
if [<$variant Request>]::IS_RESTRICTED && $handler.is_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);
|
||||||
|
|
Loading…
Reference in a new issue