add blockchain_context msgs

This commit is contained in:
hinto.janai 2024-09-24 18:27:46 -04:00
parent e8de295b57
commit dfbdec3157
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
8 changed files with 153 additions and 17 deletions

View file

@ -14,5 +14,6 @@
mod address_book; mod address_book;
mod blockchain; mod blockchain;
mod blockchain_context;
mod blockchain_manager; mod blockchain_manager;
mod txpool; mod txpool;

View file

@ -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<BlockChainContext, Error> {
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<Infallible, Error> {
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<Infallible, Error> {
let BlockChainContextResponse::FeeEstimate(hf_info) = service
.ready()
.await
.expect("TODO")
.call(BlockChainContextRequest::FeeEstimate { grace_blocks })
.await
.expect("TODO")
else {
unreachable!();
};
Ok(hf_info)
}

View file

@ -230,7 +230,7 @@ where
let BlockChainContextResponse::Context(checked_context) = context_svc let BlockChainContextResponse::Context(checked_context) = context_svc
.ready() .ready()
.await? .await?
.call(BlockChainContextRequest::GetContext) .call(BlockChainContextRequest::Context)
.await? .await?
else { else {
panic!("Context service returned wrong response!"); panic!("Context service returned wrong response!");

View file

@ -337,7 +337,7 @@ where
let BlockChainContextResponse::Context(checked_context) = context_svc let BlockChainContextResponse::Context(checked_context) = context_svc
.ready() .ready()
.await? .await?
.call(BlockChainContextRequest::GetContext) .call(BlockChainContextRequest::Context)
.await? .await?
else { else {
panic!("Context service returned wrong response!"); panic!("Context service returned wrong response!");
@ -360,7 +360,7 @@ where
let BlockChainContextResponse::RxVms(rx_vms) = context_svc let BlockChainContextResponse::RxVms(rx_vms) = context_svc
.ready() .ready()
.await? .await?
.call(BlockChainContextRequest::GetCurrentRxVm) .call(BlockChainContextRequest::CurrentRxVm)
.await? .await?
else { else {
panic!("Blockchain context service returned wrong response!"); panic!("Blockchain context service returned wrong response!");
@ -419,7 +419,7 @@ where
context context
} else { } else {
let BlockChainContextResponse::Context(checked_context) = context_svc let BlockChainContextResponse::Context(checked_context) = context_svc
.oneshot(BlockChainContextRequest::GetContext) .oneshot(BlockChainContextRequest::Context)
.await? .await?
else { else {
panic!("Context service returned wrong response!"); panic!("Context service returned wrong response!");

View file

@ -93,7 +93,7 @@ where
let BlockChainContextResponse::Context(checked_context) = context_svc let BlockChainContextResponse::Context(checked_context) = context_svc
.ready() .ready()
.await? .await?
.call(BlockChainContextRequest::GetContext) .call(BlockChainContextRequest::Context)
.await? .await?
else { else {
panic!("Context service returned wrong response!"); panic!("Context service returned wrong response!");
@ -136,7 +136,7 @@ where
let BlockChainContextResponse::RxVms(rx_vms) = context_svc let BlockChainContextResponse::RxVms(rx_vms) = context_svc
.ready() .ready()
.await? .await?
.call(BlockChainContextRequest::GetCurrentRxVm) .call(BlockChainContextRequest::CurrentRxVm)
.await? .await?
else { else {
panic!("Blockchain context service returned wrong response!"); panic!("Blockchain context service returned wrong response!");

View file

@ -221,15 +221,18 @@ pub struct NewBlockData {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum BlockChainContextRequest { pub enum BlockChainContextRequest {
/// Get the current blockchain context. /// Get the current blockchain context.
GetContext, Context,
/// Gets the current `RandomX` VM. /// Gets the current `RandomX` VM.
GetCurrentRxVm, CurrentRxVm,
/// Get the next difficulties for these blocks. /// Get the next difficulties for these blocks.
/// ///
/// Inputs: a list of block timestamps and hfs /// Inputs: a list of block timestamps and hfs
/// ///
/// The number of difficulties returned will be one more than the number of timestamps/ hfs. /// The number of difficulties returned will be one more than the number of timestamps/ hfs.
BatchGetDifficulties(Vec<(u64, HardFork)>), BatchGetDifficulties(Vec<(u64, HardFork)>),
/// Add a VM that has been created outside of the blockchain context service to the blockchain context. /// 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, /// 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 /// 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. /// This should include the seed used to init this VM and the VM.
NewRXVM(([u8; 32], Arc<RandomXVm>)), NewRXVM(([u8; 32], Arc<RandomXVm>)),
/// A request to add a new block to the cache. /// A request to add a new block to the cache.
Update(NewBlockData), Update(NewBlockData),
/// Pop blocks from the cache to the specified height. /// Pop blocks from the cache to the specified height.
PopBlocks { PopBlocks {
/// The number of blocks to pop from the top of the chain. /// 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. /// This will panic if the number of blocks will pop the genesis block.
numb_blocks: usize, numb_blocks: usize,
}, },
/// Clear the alt chain context caches. /// Clear the alt chain context caches.
ClearAltCache, ClearAltCache,
//----------------------------------------------------------------------------------------------------------- AltChainRequests //----------------------------------------------------------------------------------------------------------- AltChainRequests
/// A request for an alt chain context cache. /// 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. /// An internal token to prevent external crates calling this request.
_token: AltChainRequestToken, _token: AltChainRequestToken,
}, },
/// A request for a difficulty cache of an alternative chin. /// 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 /// 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. /// An internal token to prevent external crates calling this request.
_token: AltChainRequestToken, _token: AltChainRequestToken,
}, },
/// A request for a block weight cache of an alternative chin. /// 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 /// 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. /// An internal token to prevent external crates calling this request.
_token: AltChainRequestToken, _token: AltChainRequestToken,
}, },
/// A request for a RX VM for an alternative chin. /// A request for a RX VM for an alternative chin.
/// ///
/// Response variant: [`BlockChainContextResponse::AltChainRxVM`]. /// Response variant: [`BlockChainContextResponse::AltChainRxVM`].
@ -295,6 +305,7 @@ pub enum BlockChainContextRequest {
/// An internal token to prevent external crates calling this request. /// An internal token to prevent external crates calling this request.
_token: AltChainRequestToken, _token: AltChainRequestToken,
}, },
/// A request to add an alt chain context cache to the context cache. /// 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 /// 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. /// An internal token to prevent external crates calling this request.
_token: AltChainRequestToken, _token: AltChainRequestToken,
}, },
/// TODO
HardForkInfo(HardFork),
/// TODO
FeeEstimate {
/// TODO
grace_blocks: u64,
}
} }
pub enum BlockChainContextResponse { 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), 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. /// A map of seed height to `RandomX` VMs.
RxVms(HashMap<usize, Arc<RandomXVm>>), RxVms(HashMap<usize, Arc<RandomXVm>>),
/// A list of difficulties. /// A list of difficulties.
BatchDifficulties(Vec<u128>), BatchDifficulties(Vec<u128>),
/// An alt chain context cache. /// An alt chain context cache.
AltChainContextCache(Box<AltChainContextCache>), AltChainContextCache(Box<AltChainContextCache>),
/// A difficulty cache for an alt chain. /// A difficulty cache for an alt chain.
AltChainDifficultyCache(DifficultyCache), AltChainDifficultyCache(DifficultyCache),
/// A randomX VM for an alt chain. /// A randomX VM for an alt chain.
AltChainRxVM(Arc<RandomXVm>), AltChainRxVM(Arc<RandomXVm>),
/// A weight cache for an alt chain /// A weight cache for an alt chain
AltChainWeightCache(BlockWeightsCache), 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. /// The blockchain context service.

View file

@ -153,7 +153,7 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
req: BlockChainContextRequest, req: BlockChainContextRequest,
) -> Result<BlockChainContextResponse, tower::BoxError> { ) -> Result<BlockChainContextResponse, tower::BoxError> {
Ok(match req { Ok(match req {
BlockChainContextRequest::GetContext => { BlockChainContextRequest::Context => {
tracing::debug!("Getting blockchain context"); tracing::debug!("Getting blockchain context");
let current_hf = self.hardfork_state.current_hardfork(); let current_hf = self.hardfork_state.current_hardfork();
@ -183,7 +183,7 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
}, },
}) })
} }
BlockChainContextRequest::GetCurrentRxVm => { BlockChainContextRequest::CurrentRxVm => {
BlockChainContextResponse::RxVms(self.rx_vm_cache.get_vms().await) BlockChainContextResponse::RxVms(self.rx_vm_cache.get_vms().await)
} }
BlockChainContextRequest::BatchGetDifficulties(blocks) => { BlockChainContextRequest::BatchGetDifficulties(blocks) => {
@ -325,6 +325,9 @@ impl<D: Database + Clone + Send + 'static> ContextTask<D> {
self.alt_chain_cache_map.add_alt_cache(prev_id, cache); self.alt_chain_cache_map.add_alt_cache(prev_id, cache);
BlockChainContextResponse::Ok BlockChainContextResponse::Ok
} }
BlockChainContextRequest::HardForkInfo(_) | BlockChainContextRequest::FeeEstimate { .. } => {
todo!()
}
}) })
} }

View file

@ -41,7 +41,7 @@ async fn context_invalidated_on_new_block() -> Result<(), tower::BoxError> {
let BlockChainContextResponse::Context(context) = ctx_svc let BlockChainContextResponse::Context(context) = ctx_svc
.clone() .clone()
.oneshot(BlockChainContextRequest::GetContext) .oneshot(BlockChainContextRequest::Context)
.await? .await?
else { else {
panic!("Context service returned wrong response!"); 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 ctx_svc = initialize_blockchain_context(TEST_CONTEXT_CONFIG, db).await?;
let BlockChainContextResponse::Context(context) = ctx_svc let BlockChainContextResponse::Context(context) =
.oneshot(BlockChainContextRequest::GetContext) ctx_svc.oneshot(BlockChainContextRequest::Context).await?
.await?
else { else {
panic!("context service returned incorrect response!") panic!("context service returned incorrect response!")
}; };