diff --git a/storage/blockchain/src/service/read.rs b/storage/blockchain/src/service/read.rs index 207da41..2114280 100644 --- a/storage/blockchain/src/service/read.rs +++ b/storage/blockchain/src/service/read.rs @@ -23,7 +23,8 @@ use cuprate_types::{ use crate::{ ops::{ block::{ - block_exists, get_block_extended_header_from_height, get_block_height, get_block_info, + block_exists, get_block_extended_header, get_block_extended_header_from_height, + get_block_height, get_block_info, }, blockchain::{cumulative_generated_coins, top_block_height}, key_image::key_image_exists, @@ -86,6 +87,7 @@ fn map_request( match request { R::BlockExtendedHeader(block) => block_extended_header(env, block), + R::BlockExtendedHeaderByHash(block) => block_extended_header_by_hash(env, block), R::BlockHash(block, chain) => block_hash(env, block, chain), R::FindBlock(_) => todo!("Add alt blocks to DB"), R::FilterUnknownHashes(hashes) => filter_unknown_hashes(env, hashes), @@ -188,6 +190,19 @@ fn block_extended_header(env: &ConcreteEnv, block_height: BlockHeight) -> Respon )) } +/// [`BlockchainReadRequest::BlockExtendedHeaderByHash`]. +#[inline] +fn block_extended_header_by_hash(env: &ConcreteEnv, block_hash: BlockHash) -> ResponseResult { + // Single-threaded, no `ThreadLocal` required. + let env_inner = env.env_inner(); + let tx_ro = env_inner.tx_ro()?; + let tables = env_inner.open_tables(&tx_ro)?; + + Ok(BlockchainResponse::BlockExtendedHeaderByHash( + get_block_extended_header(&block_hash, &tables)?, + )) +} + /// [`BlockchainReadRequest::BlockHash`]. #[inline] fn block_hash(env: &ConcreteEnv, block_height: BlockHeight, chain: Chain) -> ResponseResult { diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index b502c3f..dcf472e 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -27,6 +27,11 @@ pub enum BlockchainReadRequest { /// The input is the block's height. BlockExtendedHeader(usize), + /// Request a block's extended header. + /// + /// The input is the block's hash. + BlockExtendedHeaderByHash([u8; 32]), + /// Request a block's hash. /// /// The input is the block's height and the chain it is on. @@ -129,6 +134,11 @@ pub enum BlockchainResponse { /// Inner value is the extended headed of the requested block. BlockExtendedHeader(ExtendedBlockHeader), + /// Response to [`BlockchainReadRequest::BlockExtendedHeaderByHash`]. + /// + /// Inner value is the extended headed of the requested block. + BlockExtendedHeaderByHash(ExtendedBlockHeader), + /// Response to [`BlockchainReadRequest::BlockHash`]. /// /// Inner value is the hash of the requested block.