From dfbdec3157f5300c399a9b24392321ef97ccb7d5 Mon Sep 17 00:00:00 2001 From: "hinto.janai" Date: Tue, 24 Sep 2024 18:27:46 -0400 Subject: [PATCH] add blockchain_context msgs --- binaries/cuprated/src/rpc/request.rs | 1 + .../src/rpc/request/blockchain_context.rs | 86 +++++++++++++++++++ consensus/fast-sync/src/fast_sync.rs | 2 +- consensus/src/block.rs | 6 +- consensus/src/block/batch_prepare.rs | 4 +- consensus/src/context.rs | 57 ++++++++++-- consensus/src/context/task.rs | 7 +- consensus/src/tests/context.rs | 7 +- 8 files changed, 153 insertions(+), 17 deletions(-) create mode 100644 binaries/cuprated/src/rpc/request/blockchain_context.rs diff --git a/binaries/cuprated/src/rpc/request.rs b/binaries/cuprated/src/rpc/request.rs index 6e59a88..fa2dab0 100644 --- a/binaries/cuprated/src/rpc/request.rs +++ b/binaries/cuprated/src/rpc/request.rs @@ -14,5 +14,6 @@ mod address_book; mod blockchain; +mod blockchain_context; mod blockchain_manager; mod txpool; diff --git a/binaries/cuprated/src/rpc/request/blockchain_context.rs b/binaries/cuprated/src/rpc/request/blockchain_context.rs new file mode 100644 index 0000000..1610069 --- /dev/null +++ b/binaries/cuprated/src/rpc/request/blockchain_context.rs @@ -0,0 +1,86 @@ +//! Functions for [`BlockChainContextRequest`] and [`BlockChainContextResponse`]. + +use std::{ + collections::{HashMap, HashSet}, + convert::Infallible, + ops::Range, + sync::Arc, +}; + +use anyhow::{anyhow, Error}; +use futures::StreamExt; +use monero_serai::block::Block; +use randomx_rs::RandomXVM; +use tower::{Service, ServiceExt}; + +use cuprate_consensus::context::{ + BlockChainContext, BlockChainContextRequest, BlockChainContextResponse, + BlockChainContextService, +}; +use cuprate_helper::{ + cast::{u64_to_usize, usize_to_u64}, + map::split_u128_into_low_high_bits, +}; +use cuprate_types::{ + blockchain::{BlockchainReadRequest, BlockchainResponse, BlockchainWriteRequest}, + Chain, ExtendedBlockHeader, HardFork, OutputOnChain, VerifiedBlockInformation, +}; + +use crate::rpc::CupratedRpcHandlerState; + +/// [`BlockChainContextRequest::Context`]. +pub(super) async fn context( + service: &mut BlockChainContextService, + height: u64, +) -> Result { + let BlockChainContextResponse::Context(context) = service + .ready() + .await + .expect("TODO") + .call(BlockChainContextRequest::Context) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(context) +} + +/// [`BlockChainContextRequest::HardForkInfo`]. +pub(super) async fn hard_fork_info( + service: &mut BlockChainContextService, + hard_fork: HardFork, +) -> Result { + let BlockChainContextResponse::HardForkInfo(hf_info) = service + .ready() + .await + .expect("TODO") + .call(BlockChainContextRequest::HardForkInfo(hard_fork)) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(hf_info) +} + +/// [`BlockChainContextRequest::FeeEstimate`]. +pub(super) async fn fee_estimate( + service: &mut BlockChainContextService, + grace_blocks: u64, +) -> Result { + let BlockChainContextResponse::FeeEstimate(hf_info) = service + .ready() + .await + .expect("TODO") + .call(BlockChainContextRequest::FeeEstimate { grace_blocks }) + .await + .expect("TODO") + else { + unreachable!(); + }; + + Ok(hf_info) +} diff --git a/consensus/fast-sync/src/fast_sync.rs b/consensus/fast-sync/src/fast_sync.rs index b4fc12b..ec4ea29 100644 --- a/consensus/fast-sync/src/fast_sync.rs +++ b/consensus/fast-sync/src/fast_sync.rs @@ -230,7 +230,7 @@ where let BlockChainContextResponse::Context(checked_context) = context_svc .ready() .await? - .call(BlockChainContextRequest::GetContext) + .call(BlockChainContextRequest::Context) .await? else { panic!("Context service returned wrong response!"); diff --git a/consensus/src/block.rs b/consensus/src/block.rs index 3d0db99..0d1ba2f 100644 --- a/consensus/src/block.rs +++ b/consensus/src/block.rs @@ -337,7 +337,7 @@ where let BlockChainContextResponse::Context(checked_context) = context_svc .ready() .await? - .call(BlockChainContextRequest::GetContext) + .call(BlockChainContextRequest::Context) .await? else { panic!("Context service returned wrong response!"); @@ -360,7 +360,7 @@ where let BlockChainContextResponse::RxVms(rx_vms) = context_svc .ready() .await? - .call(BlockChainContextRequest::GetCurrentRxVm) + .call(BlockChainContextRequest::CurrentRxVm) .await? else { panic!("Blockchain context service returned wrong response!"); @@ -419,7 +419,7 @@ where context } else { let BlockChainContextResponse::Context(checked_context) = context_svc - .oneshot(BlockChainContextRequest::GetContext) + .oneshot(BlockChainContextRequest::Context) .await? else { panic!("Context service returned wrong response!"); diff --git a/consensus/src/block/batch_prepare.rs b/consensus/src/block/batch_prepare.rs index 9c77848..123ec6c 100644 --- a/consensus/src/block/batch_prepare.rs +++ b/consensus/src/block/batch_prepare.rs @@ -93,7 +93,7 @@ where let BlockChainContextResponse::Context(checked_context) = context_svc .ready() .await? - .call(BlockChainContextRequest::GetContext) + .call(BlockChainContextRequest::Context) .await? else { panic!("Context service returned wrong response!"); @@ -136,7 +136,7 @@ where let BlockChainContextResponse::RxVms(rx_vms) = context_svc .ready() .await? - .call(BlockChainContextRequest::GetCurrentRxVm) + .call(BlockChainContextRequest::CurrentRxVm) .await? else { panic!("Blockchain context service returned wrong response!"); diff --git a/consensus/src/context.rs b/consensus/src/context.rs index 5bdb1ce..7778e30 100644 --- a/consensus/src/context.rs +++ b/consensus/src/context.rs @@ -221,15 +221,18 @@ pub struct NewBlockData { #[derive(Debug, Clone)] pub enum BlockChainContextRequest { /// Get the current blockchain context. - GetContext, + Context, + /// Gets the current `RandomX` VM. - GetCurrentRxVm, + CurrentRxVm, + /// Get the next difficulties for these blocks. /// /// Inputs: a list of block timestamps and hfs /// /// The number of difficulties returned will be one more than the number of timestamps/ hfs. BatchGetDifficulties(Vec<(u64, HardFork)>), + /// Add a VM that has been created outside of the blockchain context service to the blockchain context. /// This is useful when batch calculating POW as you may need to create a new VM if you batch a lot of blocks together, /// it would be wasteful to then not give this VM to the context service to then use when it needs to init a VM with the same @@ -237,8 +240,10 @@ pub enum BlockChainContextRequest { /// /// This should include the seed used to init this VM and the VM. NewRXVM(([u8; 32], Arc)), + /// A request to add a new block to the cache. Update(NewBlockData), + /// Pop blocks from the cache to the specified height. PopBlocks { /// The number of blocks to pop from the top of the chain. @@ -248,8 +253,10 @@ pub enum BlockChainContextRequest { /// This will panic if the number of blocks will pop the genesis block. numb_blocks: usize, }, + /// Clear the alt chain context caches. ClearAltCache, + //----------------------------------------------------------------------------------------------------------- AltChainRequests /// A request for an alt chain context cache. /// @@ -261,6 +268,7 @@ pub enum BlockChainContextRequest { /// An internal token to prevent external crates calling this request. _token: AltChainRequestToken, }, + /// A request for a difficulty cache of an alternative chin. /// /// This variant is private and is not callable from outside this crate, the block verifier service will @@ -271,6 +279,7 @@ pub enum BlockChainContextRequest { /// An internal token to prevent external crates calling this request. _token: AltChainRequestToken, }, + /// A request for a block weight cache of an alternative chin. /// /// This variant is private and is not callable from outside this crate, the block verifier service will @@ -281,6 +290,7 @@ pub enum BlockChainContextRequest { /// An internal token to prevent external crates calling this request. _token: AltChainRequestToken, }, + /// A request for a RX VM for an alternative chin. /// /// Response variant: [`BlockChainContextResponse::AltChainRxVM`]. @@ -295,6 +305,7 @@ pub enum BlockChainContextRequest { /// An internal token to prevent external crates calling this request. _token: AltChainRequestToken, }, + /// A request to add an alt chain context cache to the context cache. /// /// This variant is private and is not callable from outside this crate, the block verifier service will @@ -307,25 +318,61 @@ pub enum BlockChainContextRequest { /// An internal token to prevent external crates calling this request. _token: AltChainRequestToken, }, + + /// TODO + HardForkInfo(HardFork), + + /// TODO + FeeEstimate { + /// TODO + grace_blocks: u64, + } } pub enum BlockChainContextResponse { - /// Blockchain context response. + /// A generic Ok response. + /// + /// Response to: + /// - [`BlockChainContextRequest::NewRXVM`] + /// - [`BlockChainContextRequest::Update`] + /// - [`BlockChainContextRequest::PopBlocks`] + /// - [`BlockChainContextRequest::ClearAltCache`] + /// - [`BlockChainContextRequest::AddAltChainContextCache`] + Ok, + + /// Response to [`BlockChainContextRequest::Context`] Context(BlockChainContext), + + // TODO: why does this return a `HashMap` when the request is `CurrentRxVm`? + /// Response to [`BlockChainContextRequest::CurrentRxVm`] + /// /// A map of seed height to `RandomX` VMs. RxVms(HashMap>), + /// A list of difficulties. BatchDifficulties(Vec), + /// An alt chain context cache. AltChainContextCache(Box), + /// A difficulty cache for an alt chain. AltChainDifficultyCache(DifficultyCache), + /// A randomX VM for an alt chain. AltChainRxVM(Arc), + /// A weight cache for an alt chain AltChainWeightCache(BlockWeightsCache), - /// A generic Ok response. - Ok, + + /// Response to [`BlockChainContextRequest::HardForkInfo`] + /// + /// TODO + HardForkInfo(std::convert::Infallible /* TODO */), + + /// Response to [`BlockChainContextRequest::FeeEstimate`] + /// + /// TODO + FeeEstimate(std::convert::Infallible /* TODO */), } /// The blockchain context service. diff --git a/consensus/src/context/task.rs b/consensus/src/context/task.rs index 82b466c..75aff94 100644 --- a/consensus/src/context/task.rs +++ b/consensus/src/context/task.rs @@ -153,7 +153,7 @@ impl ContextTask { req: BlockChainContextRequest, ) -> Result { Ok(match req { - BlockChainContextRequest::GetContext => { + BlockChainContextRequest::Context => { tracing::debug!("Getting blockchain context"); let current_hf = self.hardfork_state.current_hardfork(); @@ -183,7 +183,7 @@ impl ContextTask { }, }) } - BlockChainContextRequest::GetCurrentRxVm => { + BlockChainContextRequest::CurrentRxVm => { BlockChainContextResponse::RxVms(self.rx_vm_cache.get_vms().await) } BlockChainContextRequest::BatchGetDifficulties(blocks) => { @@ -325,6 +325,9 @@ impl ContextTask { self.alt_chain_cache_map.add_alt_cache(prev_id, cache); BlockChainContextResponse::Ok } + BlockChainContextRequest::HardForkInfo(_) | BlockChainContextRequest::FeeEstimate { .. } => { + todo!() + } }) } diff --git a/consensus/src/tests/context.rs b/consensus/src/tests/context.rs index bbf7bb0..fdef0ac 100644 --- a/consensus/src/tests/context.rs +++ b/consensus/src/tests/context.rs @@ -41,7 +41,7 @@ async fn context_invalidated_on_new_block() -> Result<(), tower::BoxError> { let BlockChainContextResponse::Context(context) = ctx_svc .clone() - .oneshot(BlockChainContextRequest::GetContext) + .oneshot(BlockChainContextRequest::Context) .await? else { panic!("Context service returned wrong response!"); @@ -81,9 +81,8 @@ async fn context_height_correct() -> Result<(), tower::BoxError> { let ctx_svc = initialize_blockchain_context(TEST_CONTEXT_CONFIG, db).await?; - let BlockChainContextResponse::Context(context) = ctx_svc - .oneshot(BlockChainContextRequest::GetContext) - .await? + let BlockChainContextResponse::Context(context) = + ctx_svc.oneshot(BlockChainContextRequest::Context).await? else { panic!("context service returned incorrect response!") };