diff --git a/binaries/cuprated/src/rpc/blockchain.rs b/binaries/cuprated/src/rpc/blockchain.rs index 848c3449..2c7ade4b 100644 --- a/binaries/cuprated/src/rpc/blockchain.rs +++ b/binaries/cuprated/src/rpc/blockchain.rs @@ -16,8 +16,8 @@ use cuprate_helper::{ map::split_u128_into_low_high_bits, }; use cuprate_types::{ - blockchain::BlockchainReadRequest, Chain, ExtendedBlockHeader, OutputOnChain, - VerifiedBlockInformation, + blockchain::{BlockchainReadRequest, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, OutputOnChain, VerifiedBlockInformation, }; use crate::rpc::{CupratedRpcHandlerState, RESTRICTED_BLOCK_COUNT, RESTRICTED_BLOCK_HEADER_RANGE}; @@ -27,7 +27,7 @@ pub(super) async fn chain_height( state: &mut CupratedRpcHandlerState, ) -> Result<(u64, [u8; 32]), Error> { let BlockchainResponse::ChainHeight(height, hash) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::ChainHeight) @@ -45,7 +45,7 @@ pub(super) async fn block( height: u64, ) -> Result { let BlockchainResponse::Block(block) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::Block(u64_to_usize(height))) @@ -63,7 +63,7 @@ pub(super) async fn block_by_hash( hash: [u8; 32], ) -> Result { let BlockchainResponse::BlockByHash(block) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::BlockByHash(hash)) @@ -81,7 +81,7 @@ pub(super) async fn block_extended_header( height: u64, ) -> Result { let BlockchainResponse::BlockExtendedHeader(header) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::BlockExtendedHeader(u64_to_usize( @@ -101,7 +101,7 @@ pub(super) async fn block_extended_header_by_hash( hash: [u8; 32], ) -> Result { let BlockchainResponse::BlockExtendedHeaderByHash(header) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::BlockExtendedHeaderByHash(hash)) @@ -119,7 +119,7 @@ pub(super) async fn block_hash( height: u64, ) -> Result<[u8; 32], Error> { let BlockchainResponse::BlockHash(hash) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::BlockHash( @@ -140,7 +140,7 @@ pub(super) async fn key_image_spent( key_image: [u8; 32], ) -> Result { let BlockchainResponse::KeyImageSpent(is_spent) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::KeyImageSpent(key_image)) @@ -158,7 +158,7 @@ pub(super) async fn outputs( outputs: HashMap>, ) -> Result>, Error> { let BlockchainResponse::Outputs(outputs) = state - .blockchain + .blockchain_read .ready() .await? .call(BlockchainReadRequest::Outputs(outputs)) @@ -170,6 +170,28 @@ pub(super) async fn outputs( Ok(outputs) } +/// [`BlockchainResponse::PopBlocks`] +pub(super) async fn pop_blocks( + state: &mut CupratedRpcHandlerState, + nblocks: u64, +) -> Result { + // TODO: we need access to `BlockchainWriteHandle` + + // let BlockchainResponse::PopBlocks(height) = state + // .blockchain_write + // .ready() + // .await? + // .call(BlockchainWriteRequest::PopBlocks(nblocks)) + // .await? + // else { + // unreachable!(); + // }; + + let height = todo!(); + + Ok(usize_to_u64(height)) +} + // FindBlock([u8; 32]), // FilterUnknownHashes(HashSet<[u8; 32]>), // BlockExtendedHeaderInRange(Range, Chain), diff --git a/binaries/cuprated/src/rpc/handler.rs b/binaries/cuprated/src/rpc/handler.rs index 0ea89349..d5054489 100644 --- a/binaries/cuprated/src/rpc/handler.rs +++ b/binaries/cuprated/src/rpc/handler.rs @@ -7,7 +7,7 @@ use futures::{channel::oneshot::channel, future::BoxFuture}; use serde::{Deserialize, Serialize}; use tower::Service; -use cuprate_blockchain::service::BlockchainReadHandle; +use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle}; use cuprate_helper::asynch::InfallibleOneshotReceiver; use cuprate_json_rpc::Id; use cuprate_rpc_interface::RpcHandler; @@ -16,7 +16,7 @@ use cuprate_rpc_types::{ json::{JsonRpcRequest, JsonRpcResponse}, other::{OtherRequest, OtherResponse}, }; -use cuprate_txpool::service::TxpoolReadHandle; +use cuprate_txpool::service::{TxpoolReadHandle, TxpoolWriteHandle}; use crate::rpc::{bin, json, other}; @@ -38,10 +38,14 @@ pub struct CupratedRpcHandlerState { pub restricted: bool, /// Read handle to the blockchain database. - pub blockchain: BlockchainReadHandle, + pub blockchain_read: BlockchainReadHandle, + // /// Write handle to the blockchain database. + // pub blockchain_write: BlockchainWriteHandle, /// Read handle to the transaction pool database. - pub txpool: TxpoolReadHandle, + pub txpool_read: TxpoolReadHandle, + // /// Write handle to the transaction pool database. + // pub txpool_write: TxpoolWriteHandle, } impl CupratedRpcHandler { diff --git a/binaries/cuprated/src/rpc/json.rs b/binaries/cuprated/src/rpc/json.rs index babfdc34..bc267f0d 100644 --- a/binaries/cuprated/src/rpc/json.rs +++ b/binaries/cuprated/src/rpc/json.rs @@ -240,7 +240,7 @@ async fn get_block_headers_range( let mut headers = Vec::with_capacity(block_len); { - let ready = state.blockchain.ready().await?; + let ready = state.blockchain_read.ready().await?; for height in request.start_height..=request.end_height { let height = u64_to_usize(height); let task = tokio::task::spawn(ready.call(BlockchainReadRequest::Block(height))); diff --git a/binaries/cuprated/src/rpc/other.rs b/binaries/cuprated/src/rpc/other.rs index 02273d4a..804a7cd9 100644 --- a/binaries/cuprated/src/rpc/other.rs +++ b/binaries/cuprated/src/rpc/other.rs @@ -396,12 +396,14 @@ async fn update( /// async fn pop_blocks( - state: CupratedRpcHandlerState, + mut state: CupratedRpcHandlerState, request: PopBlocksRequest, ) -> Result { + let height = blockchain::pop_blocks(&mut state, request.nblocks).await?; + Ok(PopBlocksResponse { base: ResponseBase::ok(), - ..todo!() + height, }) } diff --git a/storage/blockchain/src/service/write.rs b/storage/blockchain/src/service/write.rs index 6f32ca2b..91292aa4 100644 --- a/storage/blockchain/src/service/write.rs +++ b/storage/blockchain/src/service/write.rs @@ -77,16 +77,19 @@ fn pop_blocks(env: &ConcreteEnv, nblocks: u64) -> ResponseResult { let result = || { let mut tables_mut = env_inner.open_tables_mut(&tx_rw)?; + let mut height = 0; + for _ in 0..nblocks { - ops::block::pop_block(&mut tables_mut)?; + (height, _, _) = ops::block::pop_block(&mut tables_mut)?; } - Ok(()) + + Ok(height) }; match result() { - Ok(()) => { + Ok(height) => { TxRw::commit(tx_rw)?; - Ok(BlockchainResponse::WriteBlock) + Ok(BlockchainResponse::PopBlocks(height)) } Err(e) => { // INVARIANT: ensure database atomicity by aborting diff --git a/types/src/blockchain.rs b/types/src/blockchain.rs index 009c6a70..219621b6 100644 --- a/types/src/blockchain.rs +++ b/types/src/blockchain.rs @@ -247,7 +247,7 @@ pub enum BlockchainResponse { WriteBlock, /// TODO - PopBlocks, + PopBlocks(usize), } //---------------------------------------------------------------------------------------------------- Tests