CRYPTONOTE_MAX_BLOCK_HEIGHT
Some checks are pending
Audit / audit (push) Waiting to run
Deny / audit (push) Waiting to run

This commit is contained in:
hinto.janai 2024-09-19 20:44:41 -04:00
parent b4b456b78a
commit 93ddbd6c5c
No known key found for this signature in database
GPG key ID: D47CE05FA175A499
20 changed files with 72 additions and 39 deletions

6
Cargo.lock generated
View file

@ -498,6 +498,7 @@ name = "cuprate-address-book"
version = "0.1.0"
dependencies = [
"borsh",
"cuprate-constants",
"cuprate-p2p-core",
"cuprate-pruning",
"cuprate-test-utils",
@ -527,6 +528,7 @@ version = "0.0.0"
dependencies = [
"bitflags 2.6.0",
"bytemuck",
"cuprate-constants",
"cuprate-database",
"cuprate-database-service",
"cuprate-helper",
@ -580,6 +582,7 @@ name = "cuprate-consensus-rules"
version = "0.1.0"
dependencies = [
"crypto-bigint",
"cuprate-constants",
"cuprate-cryptonight",
"cuprate-helper",
"cuprate-types",
@ -707,6 +710,7 @@ version = "0.1.0"
dependencies = [
"chrono",
"crossbeam",
"cuprate-constants",
"curve25519-dalek",
"dirs",
"futures",
@ -751,6 +755,7 @@ dependencies = [
"bytes",
"cuprate-address-book",
"cuprate-async-buffer",
"cuprate-constants",
"cuprate-fixed-bytes",
"cuprate-helper",
"cuprate-p2p-core",
@ -805,6 +810,7 @@ name = "cuprate-pruning"
version = "0.1.0"
dependencies = [
"borsh",
"cuprate-constants",
"thiserror",
]

View file

@ -11,6 +11,7 @@ proptest = ["dep:proptest", "dep:proptest-derive", "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,7 @@
use monero_serai::transaction::{Input, Output, Timelock, Transaction};
use cuprate_constants::block::MAX_BLOCK_HEIGHT;
use cuprate_helper::cast::u64_to_usize;
use cuprate_types::TxVersion;
use crate::{is_decomposed_amount, transactions::check_output_types, HardFork};
@ -112,7 +114,7 @@ fn check_time_lock(time_lock: &Timelock, chain_height: usize) -> Result<(), Mine
&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 > u64_to_usize(MAX_BLOCK_HEIGHT) {
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+1,
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));

View file

@ -3,4 +3,4 @@ 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`].
## Static data
This crate also contains `static` data used in multiple places such as the [`GENESIS_BLOCK`].
This crate also contains `static` data used in multiple places such as the [`GENESIS_BLOCK`].

View file

@ -4,4 +4,8 @@ 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: usize = 500_000_000;
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;

View file

@ -15,8 +15,8 @@
/// ```
pub const COMMIT: &str = core::env!("COMMIT"); // Set in `helper/build.rs`.
/// TODO
/// `true` if debug build, else `false`.
pub const DEBUG: bool = cfg!(debug_assertions);
/// TODO
/// `true` if release build, else `false`.
pub const RELEASE: bool = !DEBUG;

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 }
crossbeam = { workspace = true, optional = true }
chrono = { workspace = true, optional = true, features = ["std", "clock"] }
dirs = { workspace = true, optional = true }

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;
/// 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-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;
/// 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-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,12 +22,13 @@ 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,
services::{PeerSyncRequest, PeerSyncResponse},
NetworkZone, PeerSyncSvc,
};
use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT};
use cuprate_pruning::PruningSeed;
use crate::{
client_pool::{ClientPool, ClientPoolDropGuard},
@ -703,8 +704,8 @@ 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 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.
@ -159,7 +160,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;
}
@ -172,10 +173,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

@ -13,13 +13,14 @@ use futures::{stream::FuturesUnordered, StreamExt};
use tokio::sync::watch;
use tower::Service;
use cuprate_constants::block::MAX_BLOCK_HEIGHT_USIZE;
use cuprate_p2p_core::{
client::InternalPeerID,
handles::ConnectionHandle,
services::{PeerSyncRequest, PeerSyncResponse},
NetworkZone,
};
use cuprate_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_HEIGHT};
use cuprate_pruning::PruningSeed;
use cuprate_wire::CoreSyncData;
use crate::{client_pool::disconnect_monitor::PeerDisconnectFut, constants::SHORT_BAN};
@ -106,13 +107,13 @@ impl<N: NetworkZone> PeerSyncSvc<N> {
.flat_map(|(_, peers)| peers)
.filter(|peer| {
if let Some(block_needed) = block_needed {
// we just use CRYPTONOTE_MAX_BLOCK_HEIGHT as the blockchain height, this only means
// we just use `MAX_BLOCK_HEIGHT_USIZE` as the blockchain height, this only means
// we don't take into account the tip blocks which are not pruned.
self.peers
.get(peer)
.unwrap()
.1
.has_full_block(block_needed, CRYPTONOTE_MAX_BLOCK_HEIGHT)
.has_full_block(block_needed, MAX_BLOCK_HEIGHT_USIZE)
} else {
true
}

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