get_block_headers_range

This commit is contained in:
hinto.janai 2024-09-08 18:33:30 -04:00
parent 0cd1cdef9c
commit f1dea834b0
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
2 changed files with 62 additions and 15 deletions

View file

@ -11,7 +11,7 @@ pub const OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION: usize = 3 * 86400;
pub const DEFAULT_PAYMENT_DIFFICULTY: usize = 1000; pub const DEFAULT_PAYMENT_DIFFICULTY: usize = 1000;
pub const DEFAULT_PAYMENT_CREDITS_PER_HASH: usize = 100; pub const DEFAULT_PAYMENT_CREDITS_PER_HASH: usize = 100;
pub const RESTRICTED_BLOCK_HEADER_RANGE: usize = 1000; pub const RESTRICTED_BLOCK_HEADER_RANGE: u64 = 1000;
pub const RESTRICTED_TRANSACTIONS_COUNT: usize = 100; pub const RESTRICTED_TRANSACTIONS_COUNT: usize = 100;
pub const RESTRICTED_SPENT_KEY_IMAGES_COUNT: usize = 5000; pub const RESTRICTED_SPENT_KEY_IMAGES_COUNT: usize = 5000;
pub const RESTRICTED_BLOCK_COUNT: usize = 1000; pub const RESTRICTED_BLOCK_COUNT: usize = 1000;

View file

@ -35,9 +35,7 @@ use cuprate_rpc_types::{
}; };
use cuprate_types::{blockchain::BlockchainReadRequest, Chain}; use cuprate_types::{blockchain::BlockchainReadRequest, Chain};
use crate::rpc::CupratedRpcHandlerState; use crate::rpc::{CupratedRpcHandlerState, RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE};
use super::RESTRICTED_BLOCK_COUNT;
/// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`]. /// Map a [`JsonRpcRequest`] to the function that will lead to a [`JsonRpcResponse`].
pub(super) async fn map_request( pub(super) async fn map_request(
@ -161,8 +159,9 @@ async fn get_block_header_by_hash(
request: GetBlockHeaderByHashRequest, request: GetBlockHeaderByHashRequest,
) -> Result<GetBlockHeaderByHashResponse, Error> { ) -> Result<GetBlockHeaderByHashResponse, Error> {
if state.restricted && request.hashes.len() > RESTRICTED_BLOCK_COUNT { if state.restricted && request.hashes.len() > RESTRICTED_BLOCK_COUNT {
let err = anyhow!("Too many block headers requested in restricted mode"); return Err(anyhow!(
return Err(err); "Too many block headers requested in restricted mode"
));
} }
async fn get( async fn get(
@ -171,13 +170,13 @@ async fn get_block_header_by_hash(
fill_pow_hash: bool, fill_pow_hash: bool,
) -> Result<BlockHeader, Error> { ) -> Result<BlockHeader, Error> {
let Ok(bytes) = hex::decode(&hex) else { let Ok(bytes) = hex::decode(&hex) else {
let err = anyhow!("Failed to parse hex representation of block hash. Hex = {hex}."); return Err(anyhow!(
return Err(err); "Failed to parse hex representation of block hash. Hex = {hex}."
));
}; };
let Ok(hash) = bytes.try_into() else { let Ok(hash) = bytes.try_into() else {
let err = anyhow!("TODO"); return Err(anyhow!("TODO"));
return Err(err);
}; };
let BlockchainResponse::BlockByHash(block) = state let BlockchainResponse::BlockByHash(block) = state
@ -227,11 +226,10 @@ async fn get_block_header_by_height(
let height = chain_height.saturating_sub(1); let height = chain_height.saturating_sub(1);
if request.height > usize_to_u64(height) { if request.height > usize_to_u64(height) {
let err = anyhow!( return Err(anyhow!(
"Requested block height: {} greater than current top block height: {height}", "Requested block height: {} greater than current top block height: {height}",
request.height request.height
); ));
return Err(err);
} }
let BlockchainResponse::Block(block) = state let BlockchainResponse::Block(block) = state
@ -251,10 +249,59 @@ async fn get_block_header_by_height(
} }
async fn get_block_headers_range( async fn get_block_headers_range(
state: CupratedRpcHandlerState, mut state: CupratedRpcHandlerState,
request: GetBlockHeadersRangeRequest, request: GetBlockHeadersRangeRequest,
) -> Result<GetBlockHeadersRangeResponse, Error> { ) -> Result<GetBlockHeadersRangeResponse, Error> {
todo!() let BlockchainResponse::ChainHeight(chain_height, _) = state
.blockchain
.ready()
.await?
.call(BlockchainReadRequest::ChainHeight)
.await?
else {
unreachable!();
};
let height = chain_height.saturating_sub(1);
let height_u64 = usize_to_u64(height);
if request.start_height >= height_u64
|| request.end_height >= height_u64
|| request.start_height > request.end_height
{
return Err(anyhow!("Invalid start/end heights"));
}
if state.restricted
&& request.end_height.saturating_sub(request.start_height) + 1
> RESTRICTED_BLOCK_HEADER_RANGE
{
return Err(anyhow!("Too many block headers requested."));
}
let block_len = u64_to_usize(request.end_height.saturating_sub(request.start_height));
let mut tasks = Vec::with_capacity(block_len);
let mut headers = Vec::with_capacity(block_len);
{
let ready = state.blockchain.ready().await?;
for block in request.start_height..=request.end_height {
let task = tokio::task::spawn(ready.call(BlockchainReadRequest::Block(height)));
tasks.push(task);
}
}
for task in tasks {
let BlockchainResponse::Block(header) = task.await?? else {
unreachable!();
};
headers.push((&header).into());
}
Ok(GetBlockHeadersRangeResponse {
base: AccessResponseBase::ok(),
headers,
})
} }
async fn get_block( async fn get_block(