From 978d72b6c14f27bd61836d90f304d766cc7a93f2 Mon Sep 17 00:00:00 2001 From: SyntheticBird <118022351+SyntheticBird45@users.noreply.github.com> Date: Wed, 16 Oct 2024 23:17:58 +0000 Subject: [PATCH] Move consensus context service into a subcrate. (#318) Co-authored-by: Boog900 --- Cargo.lock | 23 +++++- Cargo.toml | 3 +- binaries/cuprated/Cargo.toml | 1 + binaries/cuprated/src/blockchain/manager.rs | 7 +- .../src/blockchain/manager/handler.rs | 8 +-- .../src/rpc/request/blockchain_context.rs | 2 +- books/architecture/src/appendix/crates.md | 3 +- consensus/Cargo.toml | 6 +- consensus/context/Cargo.toml | 24 +++++++ .../context => context/src}/alt_chains.rs | 13 ++-- .../context => context/src}/difficulty.rs | 23 +++--- .../{src/context => context/src}/hardforks.rs | 28 ++++---- .../{src/context.rs => context/src/lib.rs} | 71 ++++++++++++++++--- .../{src/context => context/src}/rx_vms.rs | 32 ++++----- .../{src/context => context/src}/task.rs | 13 ++-- .../{src/context => context/src}/tokens.rs | 0 .../{src/context => context/src}/weight.rs | 16 ++--- consensus/fast-sync/Cargo.toml | 13 ++-- consensus/fast-sync/src/fast_sync.rs | 6 +- consensus/src/block.rs | 4 +- consensus/src/block/alt_block.rs | 12 ++-- consensus/src/block/batch_prepare.rs | 2 +- consensus/src/lib.rs | 3 +- consensus/src/tests/context.rs | 12 ++-- consensus/src/tests/context/difficulty.rs | 2 +- consensus/src/tests/context/hardforks.rs | 10 ++- consensus/src/tests/context/rx_vms.rs | 6 +- consensus/src/tests/context/weight.rs | 8 +-- 28 files changed, 218 insertions(+), 133 deletions(-) create mode 100644 consensus/context/Cargo.toml rename consensus/{src/context => context/src}/alt_chains.rs (94%) rename consensus/{src/context => context/src}/difficulty.rs (95%) rename consensus/{src/context => context/src}/hardforks.rs (90%) rename consensus/{src/context.rs => context/src/lib.rs} (88%) rename consensus/{src/context => context/src}/rx_vms.rs (90%) rename consensus/{src/context => context/src}/task.rs (96%) rename consensus/{src/context => context/src}/tokens.rs (100%) rename consensus/{src/context => context/src}/weight.rs (96%) diff --git a/Cargo.lock b/Cargo.lock index 1b05efadb..ca0174ba6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -575,6 +575,7 @@ name = "cuprate-consensus" version = "0.1.0" dependencies = [ "cfg-if", + "cuprate-consensus-context", "cuprate-consensus-rules", "cuprate-helper", "cuprate-test-utils", @@ -587,12 +588,30 @@ dependencies = [ "proptest", "proptest-derive", "rand", - "randomx-rs", "rayon", "thiserror", "thread_local", "tokio", "tokio-test", + "tower 0.5.1", + "tracing", +] + +[[package]] +name = "cuprate-consensus-context" +version = "0.1.0" +dependencies = [ + "cuprate-consensus-rules", + "cuprate-helper", + "cuprate-types", + "futures", + "hex", + "monero-serai", + "randomx-rs", + "rayon", + "thiserror", + "thread_local", + "tokio", "tokio-util", "tower 0.5.1", "tracing", @@ -704,6 +723,7 @@ dependencies = [ "clap", "cuprate-blockchain", "cuprate-consensus", + "cuprate-consensus-context", "cuprate-consensus-rules", "cuprate-helper", "cuprate-types", @@ -972,6 +992,7 @@ dependencies = [ "cuprate-async-buffer", "cuprate-blockchain", "cuprate-consensus", + "cuprate-consensus-context", "cuprate-consensus-rules", "cuprate-cryptonight", "cuprate-dandelion-tower", diff --git a/Cargo.toml b/Cargo.toml index 6c322fbd8..2ef99d62d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "binaries/cuprated", "constants", "consensus", + "consensus/context", "consensus/fast-sync", "consensus/rules", "cryptonight", @@ -322,4 +323,4 @@ non_camel_case_types = "deny" # unused_results = "deny" # non_exhaustive_omitted_patterns = "deny" # missing_docs = "deny" -# missing_copy_implementations = "deny" \ No newline at end of file +# missing_copy_implementations = "deny" diff --git a/binaries/cuprated/Cargo.toml b/binaries/cuprated/Cargo.toml index 325406bf7..59fa9784e 100644 --- a/binaries/cuprated/Cargo.toml +++ b/binaries/cuprated/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/binaries/cuprated" # TODO: after v1.0.0, remove unneeded dependencies. cuprate-consensus = { path = "../../consensus" } cuprate-fast-sync = { path = "../../consensus/fast-sync" } +cuprate-consensus-context = { path = "../../consensus/context" } cuprate-consensus-rules = { path = "../../consensus/rules" } cuprate-cryptonight = { path = "../../cryptonight" } cuprate-helper = { path = "../../helper" } diff --git a/binaries/cuprated/src/blockchain/manager.rs b/binaries/cuprated/src/blockchain/manager.rs index 118c8dd62..8e613bc98 100644 --- a/binaries/cuprated/src/blockchain/manager.rs +++ b/binaries/cuprated/src/blockchain/manager.rs @@ -8,10 +8,11 @@ use tracing::error; use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle}; use cuprate_consensus::{ - context::RawBlockChainContext, BlockChainContextRequest, BlockChainContextResponse, - BlockChainContextService, BlockVerifierService, ExtendedConsensusError, TxVerifierService, - VerifyBlockRequest, VerifyBlockResponse, VerifyTxRequest, VerifyTxResponse, + BlockChainContextRequest, BlockChainContextResponse, BlockChainContextService, + BlockVerifierService, ExtendedConsensusError, TxVerifierService, VerifyBlockRequest, + VerifyBlockResponse, VerifyTxRequest, VerifyTxResponse, }; +use cuprate_consensus_context::RawBlockChainContext; use cuprate_p2p::{ block_downloader::{BlockBatch, BlockDownloaderConfig}, BroadcastSvc, NetworkInterface, diff --git a/binaries/cuprated/src/blockchain/manager/handler.rs b/binaries/cuprated/src/blockchain/manager/handler.rs index 9603bad54..e9805cd7a 100644 --- a/binaries/cuprated/src/blockchain/manager/handler.rs +++ b/binaries/cuprated/src/blockchain/manager/handler.rs @@ -10,11 +10,11 @@ use tracing::info; use cuprate_blockchain::service::{BlockchainReadHandle, BlockchainWriteHandle}; use cuprate_consensus::{ - block::PreparedBlock, context::NewBlockData, transactions::new_tx_verification_data, - BlockChainContextRequest, BlockChainContextResponse, BlockVerifierService, - ExtendedConsensusError, VerifyBlockRequest, VerifyBlockResponse, VerifyTxRequest, - VerifyTxResponse, + block::PreparedBlock, transactions::new_tx_verification_data, BlockChainContextRequest, + BlockChainContextResponse, BlockVerifierService, ExtendedConsensusError, VerifyBlockRequest, + VerifyBlockResponse, VerifyTxRequest, VerifyTxResponse, }; +use cuprate_consensus_context::NewBlockData; use cuprate_helper::cast::usize_to_u64; use cuprate_p2p::{block_downloader::BlockBatch, constants::LONG_BAN, BroadcastRequest}; use cuprate_types::{ diff --git a/binaries/cuprated/src/rpc/request/blockchain_context.rs b/binaries/cuprated/src/rpc/request/blockchain_context.rs index b616593d4..2b14d467f 100644 --- a/binaries/cuprated/src/rpc/request/blockchain_context.rs +++ b/binaries/cuprated/src/rpc/request/blockchain_context.rs @@ -5,7 +5,7 @@ use std::convert::Infallible; use anyhow::Error; use tower::{Service, ServiceExt}; -use cuprate_consensus::context::{ +use cuprate_consensus_context::{ BlockChainContext, BlockChainContextRequest, BlockChainContextResponse, BlockChainContextService, }; diff --git a/books/architecture/src/appendix/crates.md b/books/architecture/src/appendix/crates.md index 1993c47e7..fe8f1f05b 100644 --- a/books/architecture/src/appendix/crates.md +++ b/books/architecture/src/appendix/crates.md @@ -16,7 +16,8 @@ cargo doc --open --package cuprate-blockchain | Crate | In-tree path | Purpose | |-------|--------------|---------| | [`cuprate-consensus`](https://doc.cuprate.org/cuprate_consensus) | [`consensus/`](https://github.com/Cuprate/cuprate/tree/main/consensus) | TODO -| [`cuprate-consensus-rules`](https://doc.cuprate.org/cuprate_consensus_rules) | [`consensus/rules/`](https://github.com/Cuprate/cuprate/tree/main/consensus-rules) | TODO +| [`cuprate-consensus-context`](https://doc.cuprate.org/cuprate_consensus_context) | [`consensus/context/`](https://github.com/Cuprate/cuprate/tree/main/consensus/context) | TODO +| [`cuprate-consensus-rules`](https://doc.cuprate.org/cuprate_consensus_rules) | [`consensus/rules/`](https://github.com/Cuprate/cuprate/tree/main/consensus/rules) | TODO | [`cuprate-fast-sync`](https://doc.cuprate.org/cuprate_fast_sync) | [`consensus/fast-sync/`](https://github.com/Cuprate/cuprate/tree/main/consensus/fast-sync) | Fast block synchronization ## Networking diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 12d97eed3..1fdee89a7 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/Cuprate/cuprate/tree/main/consensus" cuprate-helper = { path = "../helper", default-features = false, features = ["std", "asynch", "num"] } cuprate-consensus-rules = { path = "./rules", features = ["rayon"] } cuprate-types = { path = "../types" } +cuprate-consensus-context = { path = "./context" } cfg-if = { workspace = true } thiserror = { workspace = true } @@ -18,13 +19,10 @@ tower = { workspace = true, features = ["util"] } tracing = { workspace = true, features = ["std", "attributes"] } futures = { workspace = true, features = ["std", "async-await"] } -randomx-rs = { workspace = true } monero-serai = { workspace = true, features = ["std"] } rayon = { workspace = true } thread_local = { workspace = true } -tokio = { workspace = true, features = ["rt"] } -tokio-util = { workspace = true } hex = { workspace = true } rand = { workspace = true } @@ -42,4 +40,4 @@ proptest = { workspace = true } proptest-derive = { workspace = true } [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/consensus/context/Cargo.toml b/consensus/context/Cargo.toml new file mode 100644 index 000000000..00804204d --- /dev/null +++ b/consensus/context/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "cuprate-consensus-context" +version = "0.1.0" +edition = "2021" +license = "MIT" +authors = ["SyntheticBird","Boog900"] + +[dependencies] +cuprate-consensus-rules = { path = "../rules", features = ["proptest"]} +cuprate-helper = { path = "../../helper", default-features = false, features = ["std", "cast"] } +cuprate-types = { path = "../../types", default-features = false } + +futures = { workspace = true, features = ["std", "async-await"] } +tokio = { workspace = true, features = ["rt-multi-thread", "macros"]} +tokio-util = { workspace = true } +tower = { workspace = true, features = ["util"] } +tracing = { workspace = true, features = ["std", "attributes"] } +thiserror = { workspace = true } + +monero-serai = { workspace = true, features = ["std"] } +randomx-rs = { workspace = true } +rayon = { workspace = true } +thread_local = { workspace = true } +hex = { workspace = true } diff --git a/consensus/src/context/alt_chains.rs b/consensus/context/src/alt_chains.rs similarity index 94% rename from consensus/src/context/alt_chains.rs rename to consensus/context/src/alt_chains.rs index cd945c819..df82ef342 100644 --- a/consensus/src/context/alt_chains.rs +++ b/consensus/context/src/alt_chains.rs @@ -9,9 +9,8 @@ use cuprate_types::{ }; use crate::{ - ExtendedConsensusError, - __private::Database, - context::{difficulty::DifficultyCache, rx_vms::RandomXVm, weight::BlockWeightsCache}, + ContextCacheError, __private::Database, difficulty::DifficultyCache, rx_vms::RandomXVm, + weight::BlockWeightsCache, }; pub(crate) mod sealed { @@ -38,7 +37,7 @@ pub struct AltChainContextCache { pub chain_height: usize, /// The top hash of the alt chain. pub top_hash: [u8; 32], - /// The [`ChainID`] of the alt chain. + /// The [`ChainId`] of the alt chain. pub chain_id: Option, /// The parent [`Chain`] of this alt chain. pub parent_chain: Chain, @@ -98,7 +97,7 @@ impl AltChainMap { &mut self, prev_id: [u8; 32], database: D, - ) -> Result, ExtendedConsensusError> { + ) -> Result, ContextCacheError> { if let Some(cache) = self.alt_cache_map.remove(&prev_id) { return Ok(cache); } @@ -133,7 +132,7 @@ pub(crate) async fn get_alt_chain_difficulty_cache( prev_id: [u8; 32], main_chain_difficulty_cache: &DifficultyCache, mut database: D, -) -> Result { +) -> Result { // find the block with hash == prev_id. let BlockchainResponse::FindBlock(res) = database .ready() @@ -180,7 +179,7 @@ pub(crate) async fn get_alt_chain_weight_cache( prev_id: [u8; 32], main_chain_weight_cache: &BlockWeightsCache, mut database: D, -) -> Result { +) -> Result { // find the block with hash == prev_id. let BlockchainResponse::FindBlock(res) = database .ready() diff --git a/consensus/src/context/difficulty.rs b/consensus/context/src/difficulty.rs similarity index 95% rename from consensus/src/context/difficulty.rs rename to consensus/context/src/difficulty.rs index 9316dc5ee..e3f558a01 100644 --- a/consensus/src/context/difficulty.rs +++ b/consensus/context/src/difficulty.rs @@ -17,7 +17,7 @@ use cuprate_types::{ Chain, }; -use crate::{Database, ExtendedConsensusError, HardFork}; +use crate::{ContextCacheError, Database, HardFork}; /// The amount of blocks we account for to calculate difficulty const DIFFICULTY_WINDOW: usize = 720; @@ -33,9 +33,9 @@ const DIFFICULTY_LAG: usize = 15; /// #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct DifficultyCacheConfig { - pub(crate) window: usize, - pub(crate) cut: usize, - pub(crate) lag: usize, + pub window: usize, + pub cut: usize, + pub lag: usize, } impl DifficultyCacheConfig { @@ -73,14 +73,13 @@ impl DifficultyCacheConfig { #[derive(Debug, Clone, Eq, PartialEq)] pub struct DifficultyCache { /// The list of timestamps in the window. - /// len <= [`DIFFICULTY_BLOCKS_COUNT`] - pub(crate) timestamps: VecDeque, + pub timestamps: VecDeque, /// The current cumulative difficulty of the chain. - pub(crate) cumulative_difficulties: VecDeque, + pub cumulative_difficulties: VecDeque, /// The last height we accounted for. - pub(crate) last_accounted_height: usize, + pub last_accounted_height: usize, /// The config - pub(crate) config: DifficultyCacheConfig, + pub config: DifficultyCacheConfig, } impl DifficultyCache { @@ -91,7 +90,7 @@ impl DifficultyCache { config: DifficultyCacheConfig, database: D, chain: Chain, - ) -> Result { + ) -> Result { tracing::info!("Initializing difficulty cache this may take a while."); let mut block_start = chain_height.saturating_sub(config.total_block_count()); @@ -134,7 +133,7 @@ impl DifficultyCache { &mut self, numb_blocks: usize, database: D, - ) -> Result<(), ExtendedConsensusError> { + ) -> Result<(), ContextCacheError> { let Some(retained_blocks) = self.timestamps.len().checked_sub(numb_blocks) else { // More blocks to pop than we have in the cache, so just restart a new cache. *self = Self::init_from_chain_height( @@ -361,7 +360,7 @@ async fn get_blocks_in_pow_info( database: D, block_heights: Range, chain: Chain, -) -> Result<(VecDeque, VecDeque), ExtendedConsensusError> { +) -> Result<(VecDeque, VecDeque), ContextCacheError> { tracing::info!("Getting blocks timestamps"); let BlockchainResponse::BlockExtendedHeaderInRange(ext_header) = database diff --git a/consensus/src/context/hardforks.rs b/consensus/context/src/hardforks.rs similarity index 90% rename from consensus/src/context/hardforks.rs rename to consensus/context/src/hardforks.rs index 16ae76384..e6af492b6 100644 --- a/consensus/src/context/hardforks.rs +++ b/consensus/context/src/hardforks.rs @@ -9,7 +9,7 @@ use cuprate_types::{ Chain, }; -use crate::{Database, ExtendedConsensusError}; +use crate::{ContextCacheError, Database}; /// The default amount of hard-fork votes to track to decide on activation of a hard-fork. /// @@ -21,9 +21,9 @@ const DEFAULT_WINDOW_SIZE: usize = 10080; // supermajority window check length - #[derive(Debug, Clone, Copy, Eq, PartialEq)] pub struct HardForkConfig { /// The network we are on. - pub(crate) info: HFsInfo, + pub info: HFsInfo, /// The amount of votes we are taking into account to decide on a fork activation. - pub(crate) window: usize, + pub window: usize, } impl HardForkConfig { @@ -54,17 +54,17 @@ impl HardForkConfig { /// A struct that keeps track of the current hard-fork and current votes. #[derive(Debug, Clone, Eq, PartialEq)] -pub(crate) struct HardForkState { +pub struct HardForkState { /// The current active hard-fork. - pub(crate) current_hardfork: HardFork, + pub current_hardfork: HardFork, /// The hard-fork config. - pub(crate) config: HardForkConfig, + pub config: HardForkConfig, /// The votes in the current window. - pub(crate) votes: HFVotes, + pub votes: HFVotes, /// The last block height accounted for. - pub(crate) last_height: usize, + pub last_height: usize, } impl HardForkState { @@ -74,7 +74,7 @@ impl HardForkState { chain_height: usize, config: HardForkConfig, mut database: D, - ) -> Result { + ) -> Result { tracing::info!("Initializing hard-fork state this may take a while."); let block_start = chain_height.saturating_sub(config.window); @@ -122,11 +122,11 @@ impl HardForkState { /// # Invariant /// /// This _must_ only be used on a main-chain cache. - pub(crate) async fn pop_blocks_main_chain( + pub async fn pop_blocks_main_chain( &mut self, numb_blocks: usize, database: D, - ) -> Result<(), ExtendedConsensusError> { + ) -> Result<(), ContextCacheError> { let Some(retained_blocks) = self.votes.total_votes().checked_sub(self.config.window) else { *self = Self::init_from_chain_height( self.last_height + 1 - numb_blocks, @@ -159,7 +159,7 @@ impl HardForkState { } /// Add a new block to the cache. - pub(crate) fn new_block(&mut self, vote: HardFork, height: usize) { + pub fn new_block(&mut self, vote: HardFork, height: usize) { // We don't _need_ to take in `height` but it's for safety, so we don't silently loose track // of blocks. assert_eq!(self.last_height + 1, height); @@ -194,7 +194,7 @@ impl HardForkState { } /// Returns the current hard-fork. - pub(crate) const fn current_hardfork(&self) -> HardFork { + pub const fn current_hardfork(&self) -> HardFork { self.current_hardfork } } @@ -205,7 +205,7 @@ async fn get_votes_in_range( database: D, block_heights: Range, window_size: usize, -) -> Result { +) -> Result { let mut votes = HFVotes::new(window_size); let BlockchainResponse::BlockExtendedHeaderInRange(vote_list) = database diff --git a/consensus/src/context.rs b/consensus/context/src/lib.rs similarity index 88% rename from consensus/src/context.rs rename to consensus/context/src/lib.rs index 3c944a926..82e601d7b 100644 --- a/consensus/src/context.rs +++ b/consensus/context/src/lib.rs @@ -1,6 +1,6 @@ //! # Blockchain Context //! -//! This module contains a service to get cached context from the blockchain: [`BlockChainContext`]. +//! This crate contains a service to get cached context from the blockchain: [`BlockChainContext`]. //! This is used during contextual validation, this does not have all the data for contextual validation //! (outputs) for that you will need a [`Database`]. //! @@ -18,14 +18,14 @@ use tokio::sync::mpsc; use tokio_util::sync::PollSender; use tower::Service; -use cuprate_consensus_rules::{blocks::ContextToVerifyBlock, current_unix_timestamp, HardFork}; - -use crate::{Database, ExtendedConsensusError}; +use cuprate_consensus_rules::{ + blocks::ContextToVerifyBlock, current_unix_timestamp, ConsensusError, HardFork, +}; -pub(crate) mod difficulty; -pub(crate) mod hardforks; -pub(crate) mod rx_vms; -pub(crate) mod weight; +pub mod difficulty; +pub mod hardforks; +pub mod rx_vms; +pub mod weight; mod alt_chains; mod task; @@ -36,13 +36,13 @@ use difficulty::DifficultyCache; use rx_vms::RandomXVm; use weight::BlockWeightsCache; -pub(crate) use alt_chains::{sealed::AltChainRequestToken, AltChainContextCache}; +pub use alt_chains::{sealed::AltChainRequestToken, AltChainContextCache}; pub use difficulty::DifficultyCacheConfig; pub use hardforks::HardForkConfig; pub use tokens::*; pub use weight::BlockWeightsCacheConfig; -pub(crate) const BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW: u64 = 60; +pub const BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW: u64 = 60; /// Config for the context service. pub struct ContextConfig { @@ -91,7 +91,7 @@ impl ContextConfig { pub async fn initialize_blockchain_context( cfg: ContextConfig, database: D, -) -> Result +) -> Result where D: Database + Clone + Send + Sync + 'static, D::Future: Send + 'static, @@ -414,3 +414,52 @@ impl Service for BlockChainContextService { .boxed() } } + +#[derive(Debug, thiserror::Error)] +pub enum ContextCacheError { + /// A consensus error. + #[error("{0}")] + ConErr(#[from] ConsensusError), + /// A database error. + #[error("Database error: {0}")] + DBErr(#[from] tower::BoxError), +} + +use __private::Database; + +pub mod __private { + use std::future::Future; + + use cuprate_types::blockchain::{BlockchainReadRequest, BlockchainResponse}; + + /// A type alias trait used to represent a database, so we don't have to write [`tower::Service`] bounds + /// everywhere. + /// + /// Automatically implemented for: + /// ```ignore + /// tower::Service + /// ``` + pub trait Database: + tower::Service< + BlockchainReadRequest, + Response = BlockchainResponse, + Error = tower::BoxError, + Future = Self::Future2, + > + { + type Future2: Future> + Send + 'static; + } + + impl< + T: tower::Service< + BlockchainReadRequest, + Response = BlockchainResponse, + Error = tower::BoxError, + >, + > Database for T + where + T::Future: Future> + Send + 'static, + { + type Future2 = T::Future; + } +} diff --git a/consensus/src/context/rx_vms.rs b/consensus/context/src/rx_vms.rs similarity index 90% rename from consensus/src/context/rx_vms.rs rename to consensus/context/src/rx_vms.rs index c6375fc13..803bb324e 100644 --- a/consensus/src/context/rx_vms.rs +++ b/consensus/context/src/rx_vms.rs @@ -26,10 +26,10 @@ use cuprate_types::{ Chain, }; -use crate::{Database, ExtendedConsensusError}; +use crate::{ContextCacheError, Database}; /// The amount of randomX VMs to keep in the cache. -const RX_SEEDS_CACHED: usize = 2; +pub const RX_SEEDS_CACHED: usize = 2; /// A multithreaded randomX VM. #[derive(Debug)] @@ -72,14 +72,14 @@ impl RandomX for RandomXVm { /// The randomX VMs cache, keeps the VM needed to calculate the current block's proof-of-work hash (if a VM is needed) and a /// couple more around this VM. #[derive(Clone, Debug)] -pub(crate) struct RandomXVmCache { +pub struct RandomXVmCache { /// The top [`RX_SEEDS_CACHED`] RX seeds. - pub(crate) seeds: VecDeque<(usize, [u8; 32])>, + pub seeds: VecDeque<(usize, [u8; 32])>, /// The VMs for `seeds` (if after hf 12, otherwise this will be empty). - pub(crate) vms: HashMap>, + pub vms: HashMap>, /// A single cached VM that was given to us from a part of Cuprate. - pub(crate) cached_vm: Option<([u8; 32], Arc)>, + pub cached_vm: Option<([u8; 32], Arc)>, } impl RandomXVmCache { @@ -88,7 +88,7 @@ impl RandomXVmCache { chain_height: usize, hf: &HardFork, database: D, - ) -> Result { + ) -> Result { let seed_heights = get_last_rx_seed_heights(chain_height - 1, RX_SEEDS_CACHED); let seed_hashes = get_block_hashes(seed_heights.clone(), database).await?; @@ -125,18 +125,18 @@ impl RandomXVmCache { } /// Add a randomX VM to the cache, with the seed it was created with. - pub(crate) fn add_vm(&mut self, vm: ([u8; 32], Arc)) { + pub fn add_vm(&mut self, vm: ([u8; 32], Arc)) { self.cached_vm.replace(vm); } /// Creates a RX VM for an alt chain, looking at the main chain RX VMs to see if we can use one /// of them first. - pub(crate) async fn get_alt_vm( + pub async fn get_alt_vm( &self, height: usize, chain: Chain, database: D, - ) -> Result, ExtendedConsensusError> { + ) -> Result, ContextCacheError> { let seed_height = randomx_seed_height(height); let BlockchainResponse::BlockHash(seed_hash) = database @@ -162,7 +162,7 @@ impl RandomXVmCache { } /// Get the main-chain `RandomX` VMs. - pub(crate) async fn get_vms(&mut self) -> HashMap> { + pub async fn get_vms(&mut self) -> HashMap> { match self.seeds.len().checked_sub(self.vms.len()) { // No difference in the amount of seeds to VMs. Some(0) => (), @@ -214,7 +214,7 @@ impl RandomXVmCache { } /// Removes all the `RandomX` VMs above the `new_height`. - pub(crate) fn pop_blocks_main_chain(&mut self, new_height: usize) { + pub fn pop_blocks_main_chain(&mut self, new_height: usize) { self.seeds.retain(|(height, _)| *height < new_height); self.vms.retain(|height, _| *height < new_height); } @@ -222,7 +222,7 @@ impl RandomXVmCache { /// Add a new block to the VM cache. /// /// hash is the block hash not the blocks proof-of-work hash. - pub(crate) fn new_block(&mut self, height: usize, hash: &[u8; 32]) { + pub fn new_block(&mut self, height: usize, hash: &[u8; 32]) { if is_randomx_seed_height(height) { tracing::debug!("Block {height} is a randomX seed height, adding it to the cache.",); @@ -243,7 +243,7 @@ impl RandomXVmCache { /// Get the last `amount` of RX seeds, the top height returned here will not necessarily be the RX VM for the top block /// in the chain as VMs include some lag before a seed activates. -pub(crate) fn get_last_rx_seed_heights(mut last_height: usize, mut amount: usize) -> Vec { +pub fn get_last_rx_seed_heights(mut last_height: usize, mut amount: usize) -> Vec { let mut seeds = Vec::with_capacity(amount); if is_randomx_seed_height(last_height) { seeds.push(last_height); @@ -268,7 +268,7 @@ pub(crate) fn get_last_rx_seed_heights(mut last_height: usize, mut amount: usize async fn get_block_hashes( heights: Vec, database: D, -) -> Result, ExtendedConsensusError> { +) -> Result, ContextCacheError> { let mut fut = FuturesOrdered::new(); for height in heights { @@ -281,7 +281,7 @@ async fn get_block_hashes( else { panic!("Database sent incorrect response!"); }; - Result::<_, ExtendedConsensusError>::Ok(hash) + Result::<_, ContextCacheError>::Ok(hash) }); } diff --git a/consensus/src/context/task.rs b/consensus/context/src/task.rs similarity index 96% rename from consensus/src/context/task.rs rename to consensus/context/src/task.rs index c51c795ea..65cfea99c 100644 --- a/consensus/src/context/task.rs +++ b/consensus/context/src/task.rs @@ -16,13 +16,10 @@ use cuprate_types::{ }; use crate::{ - context::{ - alt_chains::{get_alt_chain_difficulty_cache, get_alt_chain_weight_cache, AltChainMap}, - difficulty, hardforks, rx_vms, weight, BlockChainContext, BlockChainContextRequest, - BlockChainContextResponse, ContextConfig, RawBlockChainContext, ValidityToken, - BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW, - }, - Database, ExtendedConsensusError, + alt_chains::{get_alt_chain_difficulty_cache, get_alt_chain_weight_cache, AltChainMap}, + difficulty, hardforks, rx_vms, weight, BlockChainContext, BlockChainContextRequest, + BlockChainContextResponse, ContextCacheError, ContextConfig, Database, RawBlockChainContext, + ValidityToken, BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW, }; /// A request from the context service to the context task. @@ -68,7 +65,7 @@ impl ContextTask { pub(crate) async fn init_context( cfg: ContextConfig, mut database: D, - ) -> Result { + ) -> Result { let ContextConfig { difficulty_cfg, weights_config, diff --git a/consensus/src/context/tokens.rs b/consensus/context/src/tokens.rs similarity index 100% rename from consensus/src/context/tokens.rs rename to consensus/context/src/tokens.rs diff --git a/consensus/src/context/weight.rs b/consensus/context/src/weight.rs similarity index 96% rename from consensus/src/context/weight.rs rename to consensus/context/src/weight.rs index e95ae6056..7f725998a 100644 --- a/consensus/src/context/weight.rs +++ b/consensus/context/src/weight.rs @@ -21,12 +21,12 @@ use cuprate_types::{ Chain, }; -use crate::{Database, ExtendedConsensusError, HardFork}; +use crate::{ContextCacheError, Database, HardFork}; /// The short term block weight window. -const SHORT_TERM_WINDOW: usize = 100; +pub const SHORT_TERM_WINDOW: usize = 100; /// The long term block weight window. -const LONG_TERM_WINDOW: usize = 100000; +pub const LONG_TERM_WINDOW: usize = 100000; /// Configuration for the block weight cache. /// @@ -80,7 +80,7 @@ impl BlockWeightsCache { config: BlockWeightsCacheConfig, database: D, chain: Chain, - ) -> Result { + ) -> Result { tracing::info!("Initializing weight cache this may take a while."); let long_term_weights = get_long_term_weight_in_range( @@ -121,7 +121,7 @@ impl BlockWeightsCache { &mut self, numb_blocks: usize, database: D, - ) -> Result<(), ExtendedConsensusError> { + ) -> Result<(), ContextCacheError> { if self.long_term_weights.window_len() <= numb_blocks { // More blocks to pop than we have in the cache, so just restart a new cache. *self = Self::init_from_chain_height( @@ -258,7 +258,7 @@ fn calculate_effective_median_block_weight( } /// Calculates a blocks long term weight. -pub(crate) fn calculate_block_long_term_weight( +pub fn calculate_block_long_term_weight( hf: HardFork, block_weight: usize, long_term_median: usize, @@ -287,7 +287,7 @@ async fn get_blocks_weight_in_range( range: Range, database: D, chain: Chain, -) -> Result, ExtendedConsensusError> { +) -> Result, ContextCacheError> { tracing::info!("getting block weights."); let BlockchainResponse::BlockExtendedHeaderInRange(ext_headers) = database @@ -311,7 +311,7 @@ async fn get_long_term_weight_in_range( range: Range, database: D, chain: Chain, -) -> Result, ExtendedConsensusError> { +) -> Result, ContextCacheError> { tracing::info!("getting block long term weights."); let BlockchainResponse::BlockExtendedHeaderInRange(ext_headers) = database diff --git a/consensus/fast-sync/Cargo.toml b/consensus/fast-sync/Cargo.toml index 1d7d97b45..aa9c8d2fb 100644 --- a/consensus/fast-sync/Cargo.toml +++ b/consensus/fast-sync/Cargo.toml @@ -9,11 +9,12 @@ name = "cuprate-fast-sync-create-hashes" path = "src/create.rs" [dependencies] -cuprate-blockchain = { path = "../../storage/blockchain" } -cuprate-consensus = { path = ".." } -cuprate-consensus-rules = { path = "../rules" } -cuprate-types = { path = "../../types" } -cuprate-helper = { path = "../../helper", features = ["cast"] } +cuprate-blockchain = { path = "../../storage/blockchain" } +cuprate-consensus = { path = ".." } +cuprate-consensus-rules = { path = "../rules" } +cuprate-consensus-context = { path = "../context" } +cuprate-types = { path = "../../types" } +cuprate-helper = { path = "../../helper", features = ["cast"] } clap = { workspace = true, features = ["derive", "std"] } hex = { workspace = true } @@ -27,4 +28,4 @@ tower = { workspace = true } [dev-dependencies] [lints] -workspace = true \ No newline at end of file +workspace = true diff --git a/consensus/fast-sync/src/fast_sync.rs b/consensus/fast-sync/src/fast_sync.rs index ec4ea297c..3764e2170 100644 --- a/consensus/fast-sync/src/fast_sync.rs +++ b/consensus/fast-sync/src/fast_sync.rs @@ -12,10 +12,8 @@ use monero_serai::{ }; use tower::{Service, ServiceExt}; -use cuprate_consensus::{ - context::{BlockChainContextRequest, BlockChainContextResponse}, - transactions::new_tx_verification_data, -}; +use cuprate_consensus::transactions::new_tx_verification_data; +use cuprate_consensus_context::{BlockChainContextRequest, BlockChainContextResponse}; use cuprate_consensus_rules::{miner_tx::MinerTxError, ConsensusError}; use cuprate_helper::cast::u64_to_usize; use cuprate_types::{VerifiedBlockInformation, VerifiedTransactionInformation}; diff --git a/consensus/src/block.rs b/consensus/src/block.rs index ceb2cbab8..3f5d749e5 100644 --- a/consensus/src/block.rs +++ b/consensus/src/block.rs @@ -14,6 +14,9 @@ use monero_serai::{ }; use tower::{Service, ServiceExt}; +use cuprate_consensus_context::{ + BlockChainContextRequest, BlockChainContextResponse, RawBlockChainContext, +}; use cuprate_helper::asynch::rayon_spawn_async; use cuprate_types::{ AltBlockInformation, TransactionVerificationData, VerifiedBlockInformation, @@ -30,7 +33,6 @@ use cuprate_consensus_rules::{ }; use crate::{ - context::{BlockChainContextRequest, BlockChainContextResponse, RawBlockChainContext}, transactions::{VerifyTxRequest, VerifyTxResponse}, Database, ExtendedConsensusError, }; diff --git a/consensus/src/block/alt_block.rs b/consensus/src/block/alt_block.rs index 3a5ea7cbe..18c27345f 100644 --- a/consensus/src/block/alt_block.rs +++ b/consensus/src/block/alt_block.rs @@ -7,6 +7,12 @@ use std::{collections::HashMap, sync::Arc}; use monero_serai::{block::Block, transaction::Input}; use tower::{Service, ServiceExt}; +use cuprate_consensus_context::{ + difficulty::DifficultyCache, + rx_vms::RandomXVm, + weight::{self, BlockWeightsCache}, + AltChainContextCache, AltChainRequestToken, BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW, +}; use cuprate_consensus_rules::{ blocks::{ check_block_pow, check_block_weight, check_timestamp, randomx_seed_height, BlockError, @@ -22,12 +28,6 @@ use cuprate_types::{ use crate::{ block::{free::pull_ordered_transactions, PreparedBlock}, - context::{ - difficulty::DifficultyCache, - rx_vms::RandomXVm, - weight::{self, BlockWeightsCache}, - AltChainContextCache, AltChainRequestToken, BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW, - }, BlockChainContextRequest, BlockChainContextResponse, ExtendedConsensusError, VerifyBlockResponse, }; diff --git a/consensus/src/block/batch_prepare.rs b/consensus/src/block/batch_prepare.rs index 029a5ae6c..ef384f5da 100644 --- a/consensus/src/block/batch_prepare.rs +++ b/consensus/src/block/batch_prepare.rs @@ -5,6 +5,7 @@ use rayon::prelude::*; use tower::{Service, ServiceExt}; use tracing::instrument; +use cuprate_consensus_context::rx_vms::RandomXVm; use cuprate_consensus_rules::{ blocks::{check_block_pow, is_randomx_seed_height, randomx_seed_height, BlockError}, hard_forks::HardForkError, @@ -15,7 +16,6 @@ use cuprate_helper::asynch::rayon_spawn_async; use crate::{ block::{free::pull_ordered_transactions, PreparedBlock, PreparedBlockExPow}, - context::rx_vms::RandomXVm, transactions::new_tx_verification_data, BlockChainContextRequest, BlockChainContextResponse, ExtendedConsensusError, VerifyBlockResponse, diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs index 7280f2ff5..f21d00b2e 100644 --- a/consensus/src/lib.rs +++ b/consensus/src/lib.rs @@ -24,13 +24,12 @@ use cuprate_consensus_rules::ConsensusError; mod batch_verifier; pub mod block; -pub mod context; #[cfg(test)] mod tests; pub mod transactions; pub use block::{BlockVerifierService, VerifyBlockRequest, VerifyBlockResponse}; -pub use context::{ +pub use cuprate_consensus_context::{ initialize_blockchain_context, BlockChainContext, BlockChainContextRequest, BlockChainContextResponse, BlockChainContextService, ContextConfig, }; diff --git a/consensus/src/tests/context.rs b/consensus/src/tests/context.rs index fdef0ac8d..b9c521777 100644 --- a/consensus/src/tests/context.rs +++ b/consensus/src/tests/context.rs @@ -2,15 +2,13 @@ use proptest::strategy::ValueTree; use proptest::{strategy::Strategy, test_runner::TestRunner}; use tower::ServiceExt; -use crate::{ - context::{ - initialize_blockchain_context, BlockChainContextRequest, BlockChainContextResponse, - ContextConfig, NewBlockData, - }, - tests::mock_db::*, - HardFork, +use cuprate_consensus_context::{ + initialize_blockchain_context, BlockChainContextRequest, BlockChainContextResponse, + ContextConfig, NewBlockData, }; +use crate::{tests::mock_db::*, HardFork}; + pub(crate) mod data; mod difficulty; mod hardforks; diff --git a/consensus/src/tests/context/difficulty.rs b/consensus/src/tests/context/difficulty.rs index d5027f508..f1c0fd97c 100644 --- a/consensus/src/tests/context/difficulty.rs +++ b/consensus/src/tests/context/difficulty.rs @@ -4,10 +4,10 @@ use proptest::collection::{size_range, vec}; use proptest::{prelude::*, prop_assert_eq, prop_compose, proptest}; use crate::{ - context::difficulty::*, tests::{context::data::DIF_3000000_3002000, mock_db::*}, HardFork, }; +use cuprate_consensus_context::difficulty::*; use cuprate_helper::num::median; use cuprate_types::Chain; diff --git a/consensus/src/tests/context/hardforks.rs b/consensus/src/tests/context/hardforks.rs index 17bd47f9b..f08002326 100644 --- a/consensus/src/tests/context/hardforks.rs +++ b/consensus/src/tests/context/hardforks.rs @@ -1,13 +1,11 @@ use proptest::{collection::vec, prelude::*}; +use cuprate_consensus_context::{hardforks::HardForkState, HardForkConfig}; use cuprate_consensus_rules::hard_forks::{HFInfo, HFsInfo, HardFork, NUMB_OF_HARD_FORKS}; -use crate::{ - context::{hardforks::HardForkState, HardForkConfig}, - tests::{ - context::data::{HFS_2678808_2688888, HFS_2688888_2689608}, - mock_db::*, - }, +use crate::tests::{ + context::data::{HFS_2678808_2688888, HFS_2688888_2689608}, + mock_db::*, }; const TEST_WINDOW_SIZE: usize = 25; diff --git a/consensus/src/tests/context/rx_vms.rs b/consensus/src/tests/context/rx_vms.rs index b1eba8e23..41c62796c 100644 --- a/consensus/src/tests/context/rx_vms.rs +++ b/consensus/src/tests/context/rx_vms.rs @@ -3,15 +3,13 @@ use std::collections::VecDeque; use proptest::prelude::*; use tokio::runtime::Builder; +use cuprate_consensus_context::rx_vms::{get_last_rx_seed_heights, RandomXVmCache}; use cuprate_consensus_rules::{ blocks::{is_randomx_seed_height, randomx_seed_height}, HardFork, }; -use crate::{ - context::rx_vms::{get_last_rx_seed_heights, RandomXVmCache}, - tests::mock_db::*, -}; +use crate::tests::mock_db::*; #[test] fn rx_heights_consistent() { diff --git a/consensus/src/tests/context/weight.rs b/consensus/src/tests/context/weight.rs index b23f8f80d..dab3979ec 100644 --- a/consensus/src/tests/context/weight.rs +++ b/consensus/src/tests/context/weight.rs @@ -1,11 +1,11 @@ use crate::{ - context::{ - weight::{calculate_block_long_term_weight, BlockWeightsCache}, - BlockWeightsCacheConfig, - }, tests::{context::data::BW_2850000_3050000, mock_db::*}, HardFork, }; +use cuprate_consensus_context::{ + weight::{calculate_block_long_term_weight, BlockWeightsCache}, + BlockWeightsCacheConfig, +}; use cuprate_types::Chain; pub(crate) const TEST_WEIGHT_CONFIG: BlockWeightsCacheConfig =