diff --git a/.github/labeler.yml b/.github/labeler.yml index cf48df1..85a15b9 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -56,6 +56,10 @@ A-cryptonight: - changed-files: - any-glob-to-any-file: cryptonight/** +A-constants: +- changed-files: + - any-glob-to-any-file: constants/** + A-storage: - changed-files: - any-glob-to-any-file: storage/** diff --git a/Cargo.lock b/Cargo.lock index ca5c154..0fc5da0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -518,6 +518,7 @@ name = "cuprate-address-book" version = "0.1.0" dependencies = [ "borsh", + "cuprate-constants", "cuprate-p2p-core", "cuprate-pruning", "cuprate-test-utils", @@ -547,6 +548,7 @@ version = "0.0.0" dependencies = [ "bitflags 2.6.0", "bytemuck", + "cuprate-constants", "cuprate-database", "cuprate-database-service", "cuprate-helper", @@ -602,6 +604,7 @@ version = "0.1.0" dependencies = [ "cfg-if", "crypto-bigint", + "cuprate-constants", "cuprate-cryptonight", "cuprate-helper", "cuprate-types", @@ -618,6 +621,10 @@ dependencies = [ "tracing", ] +[[package]] +name = "cuprate-constants" +version = "0.1.0" + [[package]] name = "cuprate-cryptonight" version = "0.1.0" @@ -719,6 +726,7 @@ version = "0.1.0" dependencies = [ "chrono", "crossbeam", + "cuprate-constants", "curve25519-dalek", "dirs", "futures", @@ -764,6 +772,7 @@ dependencies = [ "bytes", "cuprate-address-book", "cuprate-async-buffer", + "cuprate-constants", "cuprate-fixed-bytes", "cuprate-helper", "cuprate-p2p-core", @@ -817,6 +826,7 @@ name = "cuprate-pruning" version = "0.1.0" dependencies = [ "borsh", + "cuprate-constants", "thiserror", ] diff --git a/Cargo.toml b/Cargo.toml index 31e9285..fa348cc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ resolver = "2" members = [ "binaries/cuprated", + "constants", "consensus", "consensus/fast-sync", "consensus/rules", diff --git a/books/architecture/src/appendix/crates.md b/books/architecture/src/appendix/crates.md index e5311a8..1993c47 100644 --- a/books/architecture/src/appendix/crates.md +++ b/books/architecture/src/appendix/crates.md @@ -55,6 +55,7 @@ cargo doc --open --package cuprate-blockchain ## 1-off crates | Crate | In-tree path | Purpose | |-------|--------------|---------| +| [`cuprate-constants`](https://doc.cuprate.org/cuprate_constants) | [`constants/`](https://github.com/Cuprate/cuprate/tree/main/constants) | Shared `const/static` data across Cuprate | [`cuprate-cryptonight`](https://doc.cuprate.org/cuprate_cryptonight) | [`cryptonight/`](https://github.com/Cuprate/cuprate/tree/main/cryptonight) | CryptoNight hash functions | [`cuprate-pruning`](https://doc.cuprate.org/cuprate_pruning) | [`pruning/`](https://github.com/Cuprate/cuprate/tree/main/pruning) | Monero pruning logic/types | [`cuprate-helper`](https://doc.cuprate.org/cuprate_helper) | [`helper/`](https://github.com/Cuprate/cuprate/tree/main/helper) | Kitchen-sink helper crate for Cuprate diff --git a/consensus/rules/Cargo.toml b/consensus/rules/Cargo.toml index ed97d33..50117ac 100644 --- a/consensus/rules/Cargo.toml +++ b/consensus/rules/Cargo.toml @@ -11,6 +11,7 @@ proptest = ["cuprate-types/proptest"] rayon = ["dep:rayon"] [dependencies] +cuprate-constants = { path = "../../constants", default-features = false } cuprate-helper = { path = "../../helper", default-features = false, features = ["std", "cast"] } cuprate-types = { path = "../../types", default-features = false } cuprate-cryptonight = {path = "../../cryptonight"} diff --git a/consensus/rules/src/miner_tx.rs b/consensus/rules/src/miner_tx.rs index e6b51d2..5221ee5 100644 --- a/consensus/rules/src/miner_tx.rs +++ b/consensus/rules/src/miner_tx.rs @@ -1,5 +1,6 @@ use monero_serai::transaction::{Input, Output, Timelock, Transaction}; +use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE; use cuprate_types::TxVersion; use crate::{is_decomposed_amount, transactions::check_output_types, HardFork}; @@ -112,7 +113,7 @@ const fn check_time_lock(time_lock: &Timelock, chain_height: usize) -> Result<() &Timelock::Block(till_height) => { // Lock times above this amount are timestamps not blocks. // This is just for safety though and shouldn't actually be hit. - if till_height > 500_000_000 { + if till_height > MAX_BLOCK_HEIGHT_USIZE { return Err(MinerTxError::InvalidLockTime); } if till_height == chain_height + MINER_TX_TIME_LOCKED_BLOCKS { diff --git a/consensus/rules/src/transactions/tests.rs b/consensus/rules/src/transactions/tests.rs index 936d843..e154396 100644 --- a/consensus/rules/src/transactions/tests.rs +++ b/consensus/rules/src/transactions/tests.rs @@ -9,6 +9,7 @@ use proptest::{collection::vec, prelude::*}; use monero_serai::transaction::Output; +use cuprate_constants::block::MAX_BLOCK_HEIGHT; use cuprate_helper::cast::u64_to_usize; use super::*; @@ -160,10 +161,10 @@ prop_compose! { /// Returns a [`Timelock`] that is locked given a height and time. fn locked_timelock(height: u64, time_for_time_lock: u64)( timebased in any::(), - lock_height in (height+1)..500_000_001, + lock_height in (height+1)..=MAX_BLOCK_HEIGHT, time_for_time_lock in (time_for_time_lock+121).., ) -> Timelock { - if timebased || lock_height > 500_000_000 { + if timebased || lock_height > MAX_BLOCK_HEIGHT { Timelock::Time(time_for_time_lock) } else { Timelock::Block(u64_to_usize(lock_height)) @@ -240,7 +241,7 @@ proptest! { } #[test] - fn test_timestamp_time_lock(timestamp in 500_000_001..u64::MAX) { + fn test_timestamp_time_lock(timestamp in MAX_BLOCK_HEIGHT+1..u64::MAX) { prop_assert!(check_timestamp_time_lock(timestamp, timestamp - 120, HardFork::V16)); prop_assert!(!check_timestamp_time_lock(timestamp, timestamp - 121, HardFork::V16)); prop_assert!(check_timestamp_time_lock(timestamp, timestamp, HardFork::V16)); diff --git a/constants/Cargo.toml b/constants/Cargo.toml new file mode 100644 index 0000000..6d3e031 --- /dev/null +++ b/constants/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "cuprate-constants" +version = "0.1.0" +edition = "2021" +description = "Constant/static data used throughout Cuprate" +license = "MIT" +authors = ["hinto-janai"] +repository = "https://github.com/Cuprate/cuprate/tree/main/constants" +keywords = ["cuprate", "constants"] + +[features] +default = [] +block = [] +build = [] +rpc = [] + +[dependencies] + +[dev-dependencies] + +[lints] +workspace = true \ No newline at end of file diff --git a/constants/README.md b/constants/README.md new file mode 100644 index 0000000..b045447 --- /dev/null +++ b/constants/README.md @@ -0,0 +1,3 @@ +# cuprate-constants +This crate contains general constants that are not specific to any particular +part of the codebase yet are used in multiple places such as the maximum block height. diff --git a/helper/build.rs b/constants/build.rs similarity index 93% rename from helper/build.rs rename to constants/build.rs index 709db42..a680714 100644 --- a/helper/build.rs +++ b/constants/build.rs @@ -1,9 +1,7 @@ fn main() { - #[cfg(feature = "constants")] set_commit_env(); } -#[cfg(feature = "constants")] /// This sets the git `COMMIT` environment variable. fn set_commit_env() { const PATH: &str = "../.git/refs/heads/"; diff --git a/constants/src/block.rs b/constants/src/block.rs new file mode 100644 index 0000000..9ddaff6 --- /dev/null +++ b/constants/src/block.rs @@ -0,0 +1,11 @@ +//! Block related. + +use crate::macros::monero_definition_link; + +/// The maximum block height possible. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 40)] +pub const MAX_BLOCK_HEIGHT: u64 = 500_000_000; + +/// [`MAX_BLOCK_HEIGHT`] as a [`usize`]. +#[expect(clippy::cast_possible_truncation, reason = "will not be truncated")] +pub const MAX_BLOCK_HEIGHT_USIZE: usize = MAX_BLOCK_HEIGHT as usize; diff --git a/constants/src/build.rs b/constants/src/build.rs new file mode 100644 index 0000000..12236ad --- /dev/null +++ b/constants/src/build.rs @@ -0,0 +1,22 @@ +//! Build related metadata. + +/// The current commit hash of the root Cuprate repository. +/// +/// # Case & length +/// It is guaranteed that `COMMIT` will be: +/// - Lowercase ASCII +/// - 40 characters long (no newline) +/// +/// ```rust +/// # use cuprate_constants::build::*; +/// assert!(COMMIT.is_ascii()); +/// assert_eq!(COMMIT.as_bytes().len(), 40); +/// assert_eq!(COMMIT.to_lowercase(), COMMIT); +/// ``` +pub const COMMIT: &str = core::env!("COMMIT"); // Set in `constants/build.rs`. + +/// `true` if debug build, else `false`. +pub const DEBUG: bool = cfg!(debug_assertions); + +/// `true` if release build, else `false`. +pub const RELEASE: bool = !DEBUG; diff --git a/constants/src/lib.rs b/constants/src/lib.rs new file mode 100644 index 0000000..f1b29fb --- /dev/null +++ b/constants/src/lib.rs @@ -0,0 +1,12 @@ +#![doc = include_str!("../README.md")] +#![deny(missing_docs, reason = "all constants should document what they are")] +#![no_std] // This can be removed if we eventually need `std`. + +mod macros; + +#[cfg(feature = "block")] +pub mod block; +#[cfg(feature = "build")] +pub mod build; +#[cfg(feature = "rpc")] +pub mod rpc; diff --git a/constants/src/macros.rs b/constants/src/macros.rs new file mode 100644 index 0000000..f41ae7b --- /dev/null +++ b/constants/src/macros.rs @@ -0,0 +1,35 @@ +/// Output a string link to `monerod` source code. +#[allow( + clippy::allow_attributes, + unused_macros, + reason = "used in feature gated modules" +)] +macro_rules! monero_definition_link { + ( + $commit:ident, // Git commit hash + $file_path:literal, // File path within `monerod`'s `src/`, e.g. `rpc/core_rpc_server_commands_defs.h` + $start:literal$(..=$end:literal)? // File lines, e.g. `0..=123` or `0` + ) => { + concat!( + "", + "[Original definition](https://github.com/monero-project/monero/blob/", + stringify!($commit), + "/src/", + $file_path, + "#L", + stringify!($start), + $( + "-L", + stringify!($end), + )? + ")." + ) + }; +} + +#[allow( + clippy::allow_attributes, + unused_imports, + reason = "used in feature gated modules" +)] +pub(crate) use monero_definition_link; diff --git a/constants/src/rpc.rs b/constants/src/rpc.rs new file mode 100644 index 0000000..1130eb7 --- /dev/null +++ b/constants/src/rpc.rs @@ -0,0 +1,101 @@ +//! RPC related. + +use core::time::Duration; + +use crate::macros::monero_definition_link; + +/// Maximum requestable block header range. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 74)] +/// +/// This is the maximum amount of blocks that can be requested +/// per invocation of `get_block_headers` if the RPC server is +/// in restricted mode. +/// +/// Used at: +/// - +pub const RESTRICTED_BLOCK_HEADER_RANGE: u64 = 1000; + +/// Maximum requestable transaction count. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 75)] +/// +/// This is the maximum amount of transactions that can be requested +/// per invocation of `get_transactions` and `get_indexes` if the +/// RPC server is in restricted mode. +/// +/// Used at: +/// - +/// - +pub const RESTRICTED_TRANSACTIONS_COUNT: usize = 100; + +/// Maximum amount of requestable key image checks. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 76)] +/// +/// This is the maximum amount of key images that can be requested +/// to be checked per `/is_key_image_spent` call if the RPC server +/// is in restricted mode. +/// +/// Used at: +/// - +/// - +pub const RESTRICTED_SPENT_KEY_IMAGES_COUNT: usize = 5000; + +/// Maximum amount of requestable blocks. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 77)] +/// +/// This is the maximum amount of blocks that can be +/// requested if the RPC server is in restricted mode. +/// +/// Used at: +/// - +/// - +pub const RESTRICTED_BLOCK_COUNT: usize = 1000; + +/// Maximum amount of fake outputs. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 67)] +/// +/// This is the maximum amount of outputs that can be +/// requested if the RPC server is in restricted mode. +/// +/// Used at: +/// - +/// - +pub const MAX_RESTRICTED_GLOBAL_FAKE_OUTS_COUNT: usize = 5000; + +/// Maximum output histrogram cutoff. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/rpc/core_rpc_server.cpp", 69)] +/// +/// This is the maximum cutoff duration allowed in `get_output_histogram` (3 days). +/// +/// ```rust +/// # use cuprate_constants::rpc::*; +/// assert_eq!(OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION.as_secs(), 86_400 * 3); +/// ``` +/// +/// Used at: +/// +pub const OUTPUT_HISTOGRAM_RECENT_CUTOFF_RESTRICTION: Duration = Duration::from_secs(86400 * 3); + +/// Maximum amount of requestable blocks in `/get_blocks.bin`. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 128)] +pub const GET_BLOCKS_BIN_MAX_BLOCK_COUNT: u64 = 1000; + +/// Maximum amount of requestable transactions in `/get_blocks.bin`. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 129)] +pub const GET_BLOCKS_BIN_MAX_TX_COUNT: u64 = 20_000; + +/// Max message content length in the RPC server. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 130)] +/// +/// This is the maximum amount of bytes an HTTP request +/// body can be before the RPC server rejects it (1 megabyte). +pub const MAX_RPC_CONTENT_LENGTH: u64 = 1_048_576; + +/// Amount of fails before blocking a remote RPC server. +#[doc = monero_definition_link!(a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623, "/src/cryptonote_config.h", 159)] +/// +/// This is the amount of times an RPC will attempt to +/// connect to another remote IP before blocking it. +/// +/// RPC servers connect to nodes when they themselves +/// lack the data to fulfill the response. +pub const RPC_IP_FAILS_BEFORE_BLOCK: u64 = 3; diff --git a/helper/Cargo.toml b/helper/Cargo.toml index 614bdb2..111c6f0 100644 --- a/helper/Cargo.toml +++ b/helper/Cargo.toml @@ -18,12 +18,14 @@ cast = [] constants = [] fs = ["dep:dirs"] num = [] -map = ["cast", "dep:monero-serai"] +map = ["cast", "dep:monero-serai", "dep:cuprate-constants"] time = ["dep:chrono", "std"] thread = ["std", "dep:target_os_lib"] tx = ["dep:monero-serai"] [dependencies] +cuprate-constants = { path = "../constants", optional = true, features = ["block"] } + crossbeam = { workspace = true, optional = true } chrono = { workspace = true, optional = true, features = ["std", "clock"] } dirs = { workspace = true, optional = true } diff --git a/helper/src/constants.rs b/helper/src/constants.rs deleted file mode 100644 index b77fad1..0000000 --- a/helper/src/constants.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! General `const`ants and `static`s. -//! -//! `#[no_std]` compatible. - -//---------------------------------------------------------------------------------------------------- Commit -/// The current commit hash of the root Cuprate repository. -/// -/// # Case & length -/// It is guaranteed that `COMMIT` will be: -/// - Lowercase -/// - 40 characters long (no newline) -/// -/// ```rust -/// # use cuprate_helper::constants::*; -/// assert_eq!(COMMIT.as_bytes().len(), 40); -/// assert_eq!(COMMIT.to_lowercase(), COMMIT); -/// ``` -pub const COMMIT: &str = core::env!("COMMIT"); // Set in `helper/build.rs`. - -//---------------------------------------------------------------------------------------------------- Tests -#[cfg(test)] -mod test {} diff --git a/helper/src/lib.rs b/helper/src/lib.rs index f29c499..bfd2fd6 100644 --- a/helper/src/lib.rs +++ b/helper/src/lib.rs @@ -11,9 +11,6 @@ pub mod atomic; #[cfg(feature = "cast")] pub mod cast; -#[cfg(feature = "constants")] -pub mod constants; - #[cfg(feature = "fs")] pub mod fs; diff --git a/helper/src/map.rs b/helper/src/map.rs index 8cf0978..b719f8f 100644 --- a/helper/src/map.rs +++ b/helper/src/map.rs @@ -7,6 +7,8 @@ //---------------------------------------------------------------------------------------------------- Use use monero_serai::transaction::Timelock; +use cuprate_constants::block::MAX_BLOCK_HEIGHT; + use crate::cast::{u64_to_usize, usize_to_u64}; //---------------------------------------------------------------------------------------------------- `(u64, u64) <-> u128` @@ -61,7 +63,7 @@ pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u12 /// Map a [`u64`] to a [`Timelock`]. /// /// Height/time is not differentiated via type, but rather: -/// "height is any value less than `500_000_000` and timestamp is any value above" +/// "height is any value less than [`MAX_BLOCK_HEIGHT`] and timestamp is any value above" /// so the `u64/usize` is stored without any tag. /// /// See [`timelock_to_u64`] for the inverse function. @@ -72,14 +74,15 @@ pub const fn combine_low_high_bits_to_u128(low_bits: u64, high_bits: u64) -> u12 /// ```rust /// # use cuprate_helper::map::*; /// # use monero_serai::transaction::*; +/// use cuprate_constants::block::{MAX_BLOCK_HEIGHT, MAX_BLOCK_HEIGHT_USIZE}; /// assert_eq!(u64_to_timelock(0), Timelock::None); -/// assert_eq!(u64_to_timelock(499_999_999), Timelock::Block(499_999_999)); -/// assert_eq!(u64_to_timelock(500_000_000), Timelock::Time(500_000_000)); +/// assert_eq!(u64_to_timelock(MAX_BLOCK_HEIGHT-1), Timelock::Block(MAX_BLOCK_HEIGHT_USIZE-1)); +/// assert_eq!(u64_to_timelock(MAX_BLOCK_HEIGHT), Timelock::Time(MAX_BLOCK_HEIGHT)); /// ``` pub const fn u64_to_timelock(u: u64) -> Timelock { if u == 0 { Timelock::None - } else if u < 500_000_000 { + } else if u < MAX_BLOCK_HEIGHT { Timelock::Block(u64_to_usize(u)) } else { Timelock::Time(u) @@ -93,9 +96,10 @@ pub const fn u64_to_timelock(u: u64) -> Timelock { /// ```rust /// # use cuprate_helper::map::*; /// # use monero_serai::transaction::*; +/// use cuprate_constants::block::{MAX_BLOCK_HEIGHT, MAX_BLOCK_HEIGHT_USIZE}; /// assert_eq!(timelock_to_u64(Timelock::None), 0); -/// assert_eq!(timelock_to_u64(Timelock::Block(499_999_999)), 499_999_999); -/// assert_eq!(timelock_to_u64(Timelock::Time(500_000_000)), 500_000_000); +/// assert_eq!(timelock_to_u64(Timelock::Block(MAX_BLOCK_HEIGHT_USIZE-1)), MAX_BLOCK_HEIGHT-1); +/// assert_eq!(timelock_to_u64(Timelock::Time(MAX_BLOCK_HEIGHT)), MAX_BLOCK_HEIGHT); /// ``` pub const fn timelock_to_u64(timelock: Timelock) -> u64 { match timelock { diff --git a/p2p/address-book/Cargo.toml b/p2p/address-book/Cargo.toml index 0871163..9afc255 100644 --- a/p2p/address-book/Cargo.toml +++ b/p2p/address-book/Cargo.toml @@ -7,6 +7,7 @@ authors = ["Boog900"] [dependencies] +cuprate-constants = { path = "../../constants" } cuprate-pruning = { path = "../../pruning" } cuprate-p2p-core = { path = "../p2p-core" } diff --git a/p2p/address-book/src/peer_list.rs b/p2p/address-book/src/peer_list.rs index 9b98a8a..fdaf336 100644 --- a/p2p/address-book/src/peer_list.rs +++ b/p2p/address-book/src/peer_list.rs @@ -3,8 +3,9 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use indexmap::IndexMap; use rand::prelude::*; +use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE; use cuprate_p2p_core::{services::ZoneSpecificPeerListEntryBase, NetZoneAddress, NetworkZone}; -use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT}; +use cuprate_pruning::PruningSeed; #[cfg(test)] pub(crate) mod tests; @@ -97,7 +98,7 @@ impl PeerList { if let Some(needed_height) = block_needed { let (_, addresses_with_block) = self.pruning_seeds.iter().find(|(seed, _)| { // TODO: factor in peer blockchain height? - seed.get_next_unpruned_block(needed_height, CRYPTONOTE_MAX_BLOCK_HEIGHT) + seed.get_next_unpruned_block(needed_height, MAX_BLOCK_HEIGHT_USIZE) .expect("Block needed is higher than max block allowed.") == needed_height })?; diff --git a/p2p/p2p/Cargo.toml b/p2p/p2p/Cargo.toml index b53baaa..3444b5e 100644 --- a/p2p/p2p/Cargo.toml +++ b/p2p/p2p/Cargo.toml @@ -6,6 +6,7 @@ license = "MIT" authors = ["Boog900"] [dependencies] +cuprate-constants = { path = "../../constants" } cuprate-fixed-bytes = { path = "../../net/fixed-bytes" } cuprate-wire = { path = "../../net/wire" } cuprate-p2p-core = { path = "../p2p-core", features = ["borsh"] } diff --git a/p2p/p2p/src/block_downloader.rs b/p2p/p2p/src/block_downloader.rs index eccb385..72eac28 100644 --- a/p2p/p2p/src/block_downloader.rs +++ b/p2p/p2p/src/block_downloader.rs @@ -22,8 +22,9 @@ use tower::{Service, ServiceExt}; use tracing::{instrument, Instrument, Span}; use cuprate_async_buffer::{BufferAppender, BufferStream}; +use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE; use cuprate_p2p_core::{handles::ConnectionHandle, NetworkZone}; -use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT}; +use cuprate_pruning::PruningSeed; use crate::{ client_pool::{ClientPool, ClientPoolDropGuard}, @@ -670,8 +671,8 @@ const fn client_has_block_in_range( start_height: usize, length: usize, ) -> bool { - pruning_seed.has_full_block(start_height, CRYPTONOTE_MAX_BLOCK_HEIGHT) - && pruning_seed.has_full_block(start_height + length, CRYPTONOTE_MAX_BLOCK_HEIGHT) + pruning_seed.has_full_block(start_height, MAX_BLOCK_HEIGHT_USIZE) + && pruning_seed.has_full_block(start_height + length, MAX_BLOCK_HEIGHT_USIZE) } /// Calculates the next amount of blocks to request in a batch. diff --git a/p2p/p2p/src/block_downloader/block_queue.rs b/p2p/p2p/src/block_downloader/block_queue.rs index 5dd1b0d..ba7c02b 100644 --- a/p2p/p2p/src/block_downloader/block_queue.rs +++ b/p2p/p2p/src/block_downloader/block_queue.rs @@ -119,12 +119,13 @@ mod tests { use proptest::{collection::vec, prelude::*}; use tokio_test::block_on; + use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE; use cuprate_p2p_core::handles::HandleBuilder; use super::*; prop_compose! { - fn ready_batch_strategy()(start_height in 0_usize..500_000_000) -> ReadyQueueBatch { + fn ready_batch_strategy()(start_height in 0..MAX_BLOCK_HEIGHT_USIZE) -> ReadyQueueBatch { let (_, peer_handle) = HandleBuilder::new().build(); ReadyQueueBatch { diff --git a/p2p/p2p/src/block_downloader/chain_tracker.rs b/p2p/p2p/src/block_downloader/chain_tracker.rs index a2f03c5..df5aebb 100644 --- a/p2p/p2p/src/block_downloader/chain_tracker.rs +++ b/p2p/p2p/src/block_downloader/chain_tracker.rs @@ -2,8 +2,9 @@ use std::{cmp::min, collections::VecDeque}; use cuprate_fixed_bytes::ByteArrayVec; +use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE; use cuprate_p2p_core::{client::InternalPeerID, handles::ConnectionHandle, NetworkZone}; -use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT}; +use cuprate_pruning::PruningSeed; use crate::constants::MEDIUM_BAN; @@ -87,7 +88,7 @@ impl ChainTracker { /// Returns `true` if the peer is expected to have the next block after our highest seen block /// according to their pruning seed. pub(crate) fn should_ask_for_next_chain_entry(&self, seed: &PruningSeed) -> bool { - seed.has_full_block(self.top_height(), CRYPTONOTE_MAX_BLOCK_HEIGHT) + seed.has_full_block(self.top_height(), MAX_BLOCK_HEIGHT_USIZE) } /// Returns the simple history, the highest seen block and the genesis block. @@ -162,7 +163,7 @@ impl ChainTracker { pruning_seed: &PruningSeed, max_blocks: usize, ) -> Option> { - if !pruning_seed.has_full_block(self.first_height, CRYPTONOTE_MAX_BLOCK_HEIGHT) { + if !pruning_seed.has_full_block(self.first_height, MAX_BLOCK_HEIGHT_USIZE) { return None; } @@ -175,10 +176,10 @@ impl ChainTracker { let end_idx = min( min(entry.ids.len(), max_blocks), pruning_seed - .get_next_pruned_block(self.first_height, CRYPTONOTE_MAX_BLOCK_HEIGHT) + .get_next_pruned_block(self.first_height, MAX_BLOCK_HEIGHT_USIZE) .expect("We use local values to calculate height which should be below the sanity limit") // Use a big value as a fallback if the seed does no pruning. - .unwrap_or(CRYPTONOTE_MAX_BLOCK_HEIGHT) + .unwrap_or(MAX_BLOCK_HEIGHT_USIZE) - self.first_height, ); diff --git a/pruning/Cargo.toml b/pruning/Cargo.toml index 497c04b..e898fd5 100644 --- a/pruning/Cargo.toml +++ b/pruning/Cargo.toml @@ -10,6 +10,8 @@ default = [] borsh = ["dep:borsh"] [dependencies] +cuprate-constants = { path = "../constants" } + thiserror = { workspace = true } borsh = { workspace = true, features = ["derive", "std"], optional = true } diff --git a/pruning/src/lib.rs b/pruning/src/lib.rs index 1f5ee2a..cd31598 100644 --- a/pruning/src/lib.rs +++ b/pruning/src/lib.rs @@ -20,9 +20,10 @@ use std::cmp::Ordering; +use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE; + use thiserror::Error; -pub const CRYPTONOTE_MAX_BLOCK_HEIGHT: usize = 500000000; /// The default log stripes for Monero pruning. pub const CRYPTONOTE_PRUNING_LOG_STRIPES: u32 = 3; /// The amount of blocks that peers keep before another stripe starts storing blocks. @@ -41,9 +42,9 @@ pub enum PruningError { LogStripesOutOfRange, #[error("Stripe is out of range")] StripeOutOfRange, - #[error("The block height is greater than `CRYPTONOTE_MAX_BLOCK_HEIGHT`")] + #[error("The block height is greater than `MAX_BLOCK_HEIGHT_USIZE`")] BlockHeightTooLarge, - #[error("The blockchain height is greater than `CRYPTONOTE_MAX_BLOCK_HEIGHT`")] + #[error("The blockchain height is greater than `MAX_BLOCK_HEIGHT_USIZE`")] BlockChainHeightTooLarge, #[error("The calculated height is smaller than the block height entered")] CalculatedHeightSmallerThanEnteredBlock, @@ -144,7 +145,7 @@ impl PruningSeed { /// ### Errors /// /// This function will return an Error if the inputted `block_height` or - /// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`]. + /// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`]. /// /// This function will also error if `block_height` > `blockchain_height` pub fn get_next_pruned_block( @@ -167,7 +168,7 @@ impl PruningSeed { /// ### Errors /// /// This function will return an Error if the inputted `block_height` or - /// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`]. + /// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`]. /// /// This function will also error if `block_height` > `blockchain_height` /// @@ -322,7 +323,7 @@ impl DecompressedPruningSeed { /// ### Errors /// /// This function will return an Error if the inputted `block_height` or - /// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`]. + /// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`]. /// /// This function will also error if `block_height` > `blockchain_height` /// @@ -331,11 +332,11 @@ impl DecompressedPruningSeed { block_height: usize, blockchain_height: usize, ) -> Result { - if block_height > CRYPTONOTE_MAX_BLOCK_HEIGHT || block_height > blockchain_height { + if block_height > MAX_BLOCK_HEIGHT_USIZE || block_height > blockchain_height { return Err(PruningError::BlockHeightTooLarge); } - if blockchain_height > CRYPTONOTE_MAX_BLOCK_HEIGHT { + if blockchain_height > MAX_BLOCK_HEIGHT_USIZE { return Err(PruningError::BlockChainHeightTooLarge); } @@ -388,7 +389,7 @@ impl DecompressedPruningSeed { /// ### Errors /// /// This function will return an Error if the inputted `block_height` or - /// `blockchain_height` is greater than [`CRYPTONOTE_MAX_BLOCK_HEIGHT`]. + /// `blockchain_height` is greater than [`MAX_BLOCK_HEIGHT_USIZE`]. /// /// This function will also error if `block_height` > `blockchain_height` /// diff --git a/storage/blockchain/Cargo.toml b/storage/blockchain/Cargo.toml index 6eecb89..0057911 100644 --- a/storage/blockchain/Cargo.toml +++ b/storage/blockchain/Cargo.toml @@ -37,6 +37,7 @@ thread_local = { workspace = true, optional = true } rayon = { workspace = true, optional = true } [dev-dependencies] +cuprate-constants = { path = "../../constants" } cuprate-helper = { path = "../../helper", features = ["thread", "cast"] } cuprate-test-utils = { path = "../../test-utils" } diff --git a/storage/blockchain/src/service/free.rs b/storage/blockchain/src/service/free.rs index d8a878c..7cc8da8 100644 --- a/storage/blockchain/src/service/free.rs +++ b/storage/blockchain/src/service/free.rs @@ -128,11 +128,13 @@ pub(super) fn map_valid_alt_block_to_verified_block( mod tests { use proptest::prelude::*; + use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE; + use super::*; proptest! { #[test] - fn compact_history(top_height in 0_usize..500_000_000) { + fn compact_history(top_height in 0..MAX_BLOCK_HEIGHT_USIZE) { let mut heights = (0..) .map(compact_history_index_to_height_offset::<11>) .map_while(|i| top_height.checked_sub(i))