Add constants/ crate (#280)
Some checks failed
Architecture mdBook / build (push) Has been cancelled
Audit / audit (push) Has been cancelled
CI / fmt (push) Has been cancelled
CI / typo (push) Has been cancelled
CI / ci (macos-latest, stable, bash) (push) Has been cancelled
CI / ci (ubuntu-latest, stable, bash) (push) Has been cancelled
CI / ci (windows-latest, stable-x86_64-pc-windows-gnu, msys2 {0}) (push) Has been cancelled
Deny / audit (push) Has been cancelled
Doc / build (push) Has been cancelled
Doc / deploy (push) Has been cancelled

* add `constants/`

* ci: add `A-constants` labeler

* add modules, move `cuprate_helper::constants`

* add `genesis.rs`

* `rpc.rs` docs

* remove todos

* `CRYPTONOTE_MAX_BLOCK_HEIGHT`

* add genesis data for all networks

* features

* fix feature cfgs

* test fixes

* add to architecture book

* fix comment

* remove `genesis` add other constants

* fixes

* revert

* fix
This commit is contained in:
hinto-janai 2024-10-02 13:51:58 -04:00 committed by GitHub
parent 521bf877db
commit a003e0588d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 276 additions and 60 deletions

4
.github/labeler.yml vendored
View file

@ -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/**

10
Cargo.lock generated
View file

@ -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",
]

View file

@ -3,6 +3,7 @@ resolver = "2"
members = [
"binaries/cuprated",
"constants",
"consensus",
"consensus/fast-sync",
"consensus/rules",

View file

@ -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

View file

@ -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"}

View file

@ -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 {

View file

@ -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::<bool>(),
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));

22
constants/Cargo.toml Normal file
View file

@ -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

3
constants/README.md Normal file
View file

@ -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.

View file

@ -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/";

11
constants/src/block.rs Normal file
View file

@ -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;

22
constants/src/build.rs Normal file
View file

@ -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;

12
constants/src/lib.rs Normal file
View file

@ -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;

35
constants/src/macros.rs Normal file
View file

@ -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;

101
constants/src/rpc.rs Normal file
View file

@ -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:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L2593>
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:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L660>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L998>
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:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L1248>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L3570>
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:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L834>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L2519>
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:
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L905>
/// - <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L935>
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:
/// <https://github.com/monero-project/monero/blob/a1dc85c5373a30f14aaf7dcfdd95f5a7375d3623/src/rpc/core_rpc_server.cpp#L2961>
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;

View file

@ -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 }

View file

@ -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 {}

View file

@ -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;

View file

@ -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 {

View file

@ -7,6 +7,7 @@ authors = ["Boog900"]
[dependencies]
cuprate-constants = { path = "../../constants" }
cuprate-pruning = { path = "../../pruning" }
cuprate-p2p-core = { path = "../p2p-core" }

View file

@ -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<Z: NetworkZone> PeerList<Z> {
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
})?;

View file

@ -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"] }

View file

@ -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.

View file

@ -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 {

View file

@ -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<N: NetworkZone> ChainTracker<N> {
/// 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<N: NetworkZone> ChainTracker<N> {
pruning_seed: &PruningSeed,
max_blocks: usize,
) -> Option<BlocksToRetrieve<N>> {
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<N: NetworkZone> ChainTracker<N> {
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,
);

View file

@ -10,6 +10,8 @@ default = []
borsh = ["dep:borsh"]
[dependencies]
cuprate-constants = { path = "../constants" }
thiserror = { workspace = true }
borsh = { workspace = true, features = ["derive", "std"], optional = true }

View file

@ -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<usize, PruningError> {
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`
///

View file

@ -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" }

View file

@ -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))

View file

@ -76,7 +76,7 @@ and should not be relied upon. This extends to any `struct/enum` that contains `
- It implements [`Env`]
- Upon [`Drop::drop`], all database data will sync to disk
Note that `ConcreteEnv` itself is not a clonable type,
Note that `ConcreteEnv` itself is not a cloneable type,
it should be wrapped in [`std::sync::Arc`].
<!-- SOMEDAY: replace `ConcreteEnv` with `fn Env::open() -> impl Env`/