diff --git a/Cargo.lock b/Cargo.lock index b73592f9..d79b9eb1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -428,31 +428,20 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cuprate-common" -version = "0.1.0" -dependencies = [ - "borsh", - "chrono", - "futures", - "hex", - "thiserror", -] - [[package]] name = "cuprate-consensus" version = "0.1.0" dependencies = [ "borsh", "clap", - "cuprate-common", + "cuprate-helper", "curve25519-dalek", "dalek-ff-group", "dirs", "futures", "hex", "monero-consensus", - "monero-epee-bin-serde 1.0.1 (git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=e4a585a)", + "monero-epee-bin-serde", "monero-serai", "monero-wire", "multiexp", @@ -472,6 +461,18 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "cuprate-helper" +version = "0.1.0" +dependencies = [ + "chrono", + "futures", + "libc", + "rayon", + "tokio", + "windows", +] + [[package]] name = "cuprate-test-utils" version = "0.1.0" @@ -816,18 +817,6 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -[[package]] -name = "helper" -version = "0.1.0" -dependencies = [ - "chrono", - "futures", - "libc", - "rayon", - "tokio", - "windows", -] - [[package]] name = "hermit-abi" version = "0.3.4" @@ -1098,10 +1087,10 @@ version = "0.1.0" dependencies = [ "async-trait", "borsh", - "cuprate-common", "cuprate-test-utils", "futures", "monero-p2p", + "monero-pruning", "monero-wire", "pin-project", "rand", @@ -1117,7 +1106,7 @@ version = "0.1.0" dependencies = [ "crypto-bigint", "cryptonight-cuprate", - "cuprate-common", + "cuprate-helper", "curve25519-dalek", "dalek-ff-group", "hex", @@ -1136,22 +1125,13 @@ dependencies = [ [[package]] name = "monero-epee-bin-serde" version = "1.0.1" -source = "git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=aafe4ba#aafe4ba1b9912b03cf616db7403628fc2bd82eb1" +source = "git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=fae7a23#fae7a23f8e57f19553c341c0878b4f0fa5a6994d" dependencies = [ "byteorder", "serde", "serde_bytes", ] -[[package]] -name = "monero-epee-bin-serde" -version = "1.0.1" -source = "git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=e4a585a#e4a585a9deda5f888ebca766d5e61a2bb987147c" -dependencies = [ - "byteorder", - "serde", -] - [[package]] name = "monero-generators" version = "0.4.0" @@ -1171,10 +1151,11 @@ version = "0.1.0" dependencies = [ "async-trait", "borsh", - "cuprate-common", + "cuprate-helper", "cuprate-test-utils", "futures", "hex", + "monero-pruning", "monero-wire", "thiserror", "tokio", @@ -1185,6 +1166,14 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "monero-pruning" +version = "0.1.0" +dependencies = [ + "borsh", + "thiserror", +] + [[package]] name = "monero-serai" version = "0.1.4-alpha" @@ -1225,7 +1214,7 @@ version = "0.1.0" dependencies = [ "hex", "levin-cuprate", - "monero-epee-bin-serde 1.0.1 (git+https://github.com/monero-rs/monero-epee-bin-serde.git?rev=aafe4ba)", + "monero-epee-bin-serde", "serde", "serde_bytes", "thiserror", diff --git a/Cargo.toml b/Cargo.toml index 84492c9d..b56473ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,18 +2,16 @@ resolver = "2" members = [ - "common", "consensus", "consensus/rules", "cryptonight", - # "cuprate", - # "database", "helper", "net/levin", "net/monero-wire", "p2p/monero-p2p", "p2p/address-book", - "test-utils" + "pruning", + "test-utils", ] [profile.release] @@ -47,7 +45,7 @@ dirs = { version = "5.0.1", default-features = false } futures = { version = "0.3.29", default-features = false } hex = { version = "0.4.3", default-features = false } hex-literal = { version = "0.4", default-features = false } -monero-epee-bin-serde = { git = "https://github.com/monero-rs/monero-epee-bin-serde.git", rev = "e4a585a", default-features = false } +monero-epee-bin-serde = { git = "https://github.com/monero-rs/monero-epee-bin-serde.git", rev = "fae7a23", default-features = false } monero-serai = { git = "https://github.com/Cuprate/serai.git", rev = "a59966b", default-features = false } multiexp = { git = "https://github.com/Cuprate/serai.git", rev = "a59966b", default-features = false } pin-project = { version = "1.1.3", default-features = false } diff --git a/common/Cargo.toml b/common/Cargo.toml deleted file mode 100644 index d20d73a7..00000000 --- a/common/Cargo.toml +++ /dev/null @@ -1,19 +0,0 @@ -[package] -name = "cuprate-common" -version = "0.1.0" -edition = "2021" -license = "AGPL-3.0-only" -authors = ["Boog900"] - -[features] -default = [] -borsh = ["dep:borsh"] - -[dependencies] -chrono = { workspace = true } -thiserror = { workspace = true } -hex = { workspace = true, features = ["std"] } - -futures = { workspace = true, features = ["std"] } - -borsh = { workspace = true, features = ["derive", "std"], optional = true } \ No newline at end of file diff --git a/common/LICENSE b/common/LICENSE deleted file mode 100644 index e19903e6..00000000 --- a/common/LICENSE +++ /dev/null @@ -1,14 +0,0 @@ - Copyright (C) 2023 Cuprate Contributors - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU Affero General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU Affero General Public License for more details. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . \ No newline at end of file diff --git a/common/src/hardforks.rs b/common/src/hardforks.rs deleted file mode 100644 index ca014cb8..00000000 --- a/common/src/hardforks.rs +++ /dev/null @@ -1,250 +0,0 @@ -use chrono::NaiveDateTime; - -use crate::network::Network; - -// this function blindly unwraps -// SAFETY: only call when you know the timestamp is good -fn time_from_timestamp(stamp: i64) -> NaiveDateTime { - NaiveDateTime::from_timestamp_opt(stamp, 0).unwrap() -} - -fn get_hard_forks(network: Network) -> [(u8, u64, NaiveDateTime); 16] { - match network { - Network::MainNet => { - [ - // | version | Height | TimeStamp | *timestamp is when fork height was decided - (1, 1, time_from_timestamp(1341378000)), - (2, 1009827, time_from_timestamp(1442763710)), - (3, 1141317, time_from_timestamp(1458558528)), - (4, 1220516, time_from_timestamp(1483574400)), - (5, 1288616, time_from_timestamp(1489520158)), - (6, 1400000, time_from_timestamp(1503046577)), - (7, 1546000, time_from_timestamp(1521303150)), - (8, 1685555, time_from_timestamp(1535889547)), - (9, 1686275, time_from_timestamp(1535889548)), - (10, 1788000, time_from_timestamp(1549792439)), - (11, 1788720, time_from_timestamp(1550225678)), - (12, 1978433, time_from_timestamp(1571419280)), - (13, 2210000, time_from_timestamp(1598180817)), - (14, 2210720, time_from_timestamp(1598180818)), - (15, 2688888, time_from_timestamp(1656629117)), - (16, 2689608, time_from_timestamp(1656629118)), - ] - } - Network::TestNet => [ - (1, 1, time_from_timestamp(1341378000)), - (2, 624634, time_from_timestamp(1445355000)), - (3, 800500, time_from_timestamp(1472415034)), - (4, 801219, time_from_timestamp(1472415035)), - (5, 802660, time_from_timestamp(1472415036 + 86400 * 180)), - (6, 971400, time_from_timestamp(1501709789)), - (7, 1057027, time_from_timestamp(1512211236)), - (8, 1057058, time_from_timestamp(1533211200)), - (9, 1057778, time_from_timestamp(1533297600)), - (10, 1154318, time_from_timestamp(1550153694)), - (11, 1155038, time_from_timestamp(1550225678)), - (12, 1308737, time_from_timestamp(1569582000)), - (13, 1543939, time_from_timestamp(1599069376)), - (14, 1544659, time_from_timestamp(1599069377)), - (15, 1982800, time_from_timestamp(1652727000)), - (16, 1983520, time_from_timestamp(1652813400)), - ], - Network::StageNet => [ - (1, 1, time_from_timestamp(1341378000)), - (2, 32000, time_from_timestamp(1521000000)), - (3, 33000, time_from_timestamp(1521120000)), - (4, 34000, time_from_timestamp(1521240000)), - (5, 35000, time_from_timestamp(1521360000)), - (6, 36000, time_from_timestamp(1521480000)), - (7, 37000, time_from_timestamp(1521600000)), - (8, 176456, time_from_timestamp(1537821770)), - (9, 177176, time_from_timestamp(1537821771)), - (10, 269000, time_from_timestamp(1550153694)), - (11, 269720, time_from_timestamp(1550225678)), - (12, 454721, time_from_timestamp(1571419280)), - (13, 675405, time_from_timestamp(1598180817)), - (14, 676125, time_from_timestamp(1598180818)), - (15, 1151000, time_from_timestamp(1656629117)), - (16, 1151720, time_from_timestamp(1656629118)), - ], - } -} - -pub struct HardForks { - hard_forks: [(u8, u64, NaiveDateTime); 16], -} - -impl HardForks { - pub fn new(network: Network) -> Self { - HardForks { - hard_forks: get_hard_forks(network), - } - } - - pub fn get_ideal_version_from_height(&self, height: u64) -> u8 { - for hf in self.hard_forks.iter().rev() { - if height >= hf.1 { - return hf.0; - } - } - 0 - } - - pub fn get_earliest_ideal_height_for_version(&self, version: u8) -> Option { - if self.hard_forks.len() < version as usize { - None - } else if version == 0 { - Some(0) - } else { - Some(self.hard_forks[(version - 1) as usize].1) - } - } - - pub fn get_ideal_version(&self) -> u8 { - self.hard_forks.last().expect("This is not empty").0 - } -} - -#[cfg(test)] -mod tests { - use crate::network::Network; - - use super::HardForks; - - const MAIN_NET_FORKS: [u64; 16] = [ - 1, 1009827, 1141317, 1220516, 1288616, 1400000, 1546000, 1685555, 1686275, 1788000, - 1788720, 1978433, 2210000, 2210720, 2688888, 2689608, - ]; - const TEST_NET_FORKS: [u64; 16] = [ - 1, 624634, 800500, 801219, 802660, 971400, 1057027, 1057058, 1057778, 1154318, 1155038, - 1308737, 1543939, 1544659, 1982800, 1983520, - ]; - const STAGE_NET_FORKS: [u64; 16] = [ - 1, 32000, 33000, 34000, 35000, 36000, 37000, 176456, 177176, 269000, 269720, 454721, - 675405, 676125, 1151000, 1151720, - ]; - - #[test] - fn get_ideal_version() { - let hardforks = HardForks::new(Network::MainNet); - - let version = hardforks.get_ideal_version(); - assert_eq!(version as usize, MAIN_NET_FORKS.len()); - assert_eq!(version as usize, TEST_NET_FORKS.len()); - assert_eq!(version as usize, STAGE_NET_FORKS.len()); - - let height = hardforks - .get_earliest_ideal_height_for_version(version) - .unwrap(); - let got_version = hardforks.get_ideal_version_from_height(height); - assert_eq!(version, got_version); - } - - #[test] - fn get_earliest_ideal_height_for_version_mainnet() { - let hardforks = HardForks::new(Network::MainNet); - - for (height, version) in MAIN_NET_FORKS.iter().zip(1..MAIN_NET_FORKS.len() as u8) { - assert_eq!( - hardforks - .get_earliest_ideal_height_for_version(version) - .unwrap(), - *height - ); - assert_eq!( - hardforks - .get_earliest_ideal_height_for_version(version) - .unwrap(), - *height - ); - } - assert!(hardforks - .get_earliest_ideal_height_for_version(MAIN_NET_FORKS.len() as u8 + 1) - .is_none()) - } - - #[test] - fn get_earliest_ideal_height_for_version_testnet() { - let hardforks = HardForks::new(Network::TestNet); - - for (height, version) in TEST_NET_FORKS.iter().zip(1..TEST_NET_FORKS.len() as u8) { - assert_eq!( - hardforks - .get_earliest_ideal_height_for_version(version) - .unwrap(), - *height - ); - assert_eq!( - hardforks - .get_earliest_ideal_height_for_version(version) - .unwrap(), - *height - ); - } - assert!(hardforks - .get_earliest_ideal_height_for_version(TEST_NET_FORKS.len() as u8 + 1) - .is_none()) - } - - #[test] - fn get_earliest_ideal_height_for_version_stagenet() { - let hardforks = HardForks::new(Network::StageNet); - - for (height, version) in STAGE_NET_FORKS.iter().zip(1..STAGE_NET_FORKS.len() as u8) { - assert_eq!( - hardforks - .get_earliest_ideal_height_for_version(version) - .unwrap(), - *height - ); - assert_eq!( - hardforks - .get_earliest_ideal_height_for_version(version) - .unwrap(), - *height - ); - } - assert!(hardforks - .get_earliest_ideal_height_for_version(STAGE_NET_FORKS.len() as u8 + 1) - .is_none()) - } - - #[test] - fn get_ideal_version_from_height_mainnet() { - let hardforks = HardForks::new(Network::MainNet); - - for (height, version) in MAIN_NET_FORKS.iter().zip(1..MAIN_NET_FORKS.len() as u8) { - assert_eq!(hardforks.get_ideal_version_from_height(*height), version); - assert_eq!( - hardforks.get_ideal_version_from_height(*height - 1), - version - 1 - ); - } - } - - #[test] - fn get_ideal_version_from_height_testnet() { - let hardforks = HardForks::new(Network::TestNet); - - for (height, version) in TEST_NET_FORKS.iter().zip(1..TEST_NET_FORKS.len() as u8) { - assert_eq!(hardforks.get_ideal_version_from_height(*height), version); - assert_eq!( - hardforks.get_ideal_version_from_height(*height - 1), - version - 1 - ); - } - } - - #[test] - fn get_ideal_version_from_height_stagenet() { - let hardforks = HardForks::new(Network::StageNet); - - for (height, version) in STAGE_NET_FORKS.iter().zip(1..STAGE_NET_FORKS.len() as u8) { - assert_eq!(hardforks.get_ideal_version_from_height(*height), version); - assert_eq!( - hardforks.get_ideal_version_from_height(*height - 1), - version - 1 - ); - } - } -} diff --git a/common/src/lib.rs b/common/src/lib.rs deleted file mode 100644 index 79bdcfdf..00000000 --- a/common/src/lib.rs +++ /dev/null @@ -1,37 +0,0 @@ -//pub mod hardforks; -pub mod network; -pub mod pruning; -pub mod tower_utils; - -use std::fmt::Formatter; -//pub use hardforks::HardForks; -pub use network::Network; -pub use pruning::{PruningError, PruningSeed}; - -pub const CRYPTONOTE_MAX_BLOCK_NUMBER: u64 = 500000000; - -// pruning -pub const CRYPTONOTE_PRUNING_LOG_STRIPES: u32 = 3; -pub const CRYPTONOTE_PRUNING_STRIPE_SIZE: u64 = 4096; -pub const CRYPTONOTE_PRUNING_TIP_BLOCKS: u64 = 5500; - -#[derive(Debug, Clone)] -pub enum BlockID { - Hash([u8; 32]), - Height(u64), -} - -impl std::fmt::Display for BlockID { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - BlockID::Hash(hash) => f.write_str(&format!("Hash: {}", hex::encode(hash))), - BlockID::Height(height) => f.write_str(&format!("Height: {}", height)), - } - } -} - -impl From for BlockID { - fn from(value: u64) -> Self { - BlockID::Height(value) - } -} diff --git a/common/src/tower_utils.rs b/common/src/tower_utils.rs deleted file mode 100644 index 6e512b0d..00000000 --- a/common/src/tower_utils.rs +++ /dev/null @@ -1,28 +0,0 @@ -use std::{ - future::Future, - pin::Pin, - task::{Context, Poll}, -}; - -use futures::channel::oneshot; -use futures::FutureExt; - -/// A oneshot that doesn't return an Error. This requires the sender to always -/// return a response. -pub struct InfallibleOneshotReceiver(oneshot::Receiver); - -impl From> for InfallibleOneshotReceiver { - fn from(value: oneshot::Receiver) -> Self { - InfallibleOneshotReceiver(value) - } -} - -impl Future for InfallibleOneshotReceiver { - type Output = T; - - fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - self.0 - .poll_unpin(cx) - .map(|res| res.expect("Oneshot must not be cancelled before response!")) - } -} diff --git a/consensus/Cargo.toml b/consensus/Cargo.toml index 64d74d65..30a13401 100644 --- a/consensus/Cargo.toml +++ b/consensus/Cargo.toml @@ -29,7 +29,7 @@ binaries = [ ] [dependencies] -cuprate-common = {path = "../common"} +cuprate-helper = { path = "../helper", default-features = false, features = ["std", "asynch", "num"] } monero-consensus = {path = "./rules", features = ["rayon"]} thiserror = { workspace = true } diff --git a/consensus/rules/Cargo.toml b/consensus/rules/Cargo.toml index 7a16341b..d553d516 100644 --- a/consensus/rules/Cargo.toml +++ b/consensus/rules/Cargo.toml @@ -9,8 +9,8 @@ proptest = ["dep:proptest", "dep:proptest-derive"] rayon = ["dep:rayon"] [dependencies] +cuprate-helper = { path = "../../helper", default-features = false, features = ["std"] } cryptonight-cuprate = {path = "../../cryptonight"} -cuprate-common = {path = "../../common"} monero-serai = { workspace = true, features = ["std"] } multiexp = { workspace = true, features = ["std", "batch"] } diff --git a/consensus/rules/src/genesis.rs b/consensus/rules/src/genesis.rs index 73ba648a..aab99a7c 100644 --- a/consensus/rules/src/genesis.rs +++ b/consensus/rules/src/genesis.rs @@ -6,7 +6,7 @@ use monero_serai::{ transaction::Transaction, }; -use cuprate_common::Network; +use cuprate_helper::network::Network; const fn genesis_nonce(network: &Network) -> u32 { match network { @@ -42,9 +42,7 @@ pub fn generate_genesis_block(network: &Network) -> Block { #[cfg(test)] mod tests { - use cuprate_common::Network; - - use super::generate_genesis_block; + use super::*; #[test] fn generate_genesis_blocks() { diff --git a/consensus/src/bin/scan_chain.rs b/consensus/src/bin/scan_chain.rs index f8178771..d8665420 100644 --- a/consensus/src/bin/scan_chain.rs +++ b/consensus/src/bin/scan_chain.rs @@ -19,7 +19,7 @@ mod bin { use tower::{Service, ServiceExt}; use tracing::level_filters::LevelFilter; - use cuprate_common::Network; + use cuprate_helper::network::Network; use cuprate_consensus::{ block::PrePreparedBlockExPOW, diff --git a/consensus/src/bin/tx_pool.rs b/consensus/src/bin/tx_pool.rs index c27c5cf8..dd596232 100644 --- a/consensus/src/bin/tx_pool.rs +++ b/consensus/src/bin/tx_pool.rs @@ -13,7 +13,7 @@ mod bin { use monero_serai::transaction::Transaction; use tower::{Service, ServiceExt}; - use cuprate_common::tower_utils::InfallibleOneshotReceiver; + use cuprate_helper::asynch::InfallibleOneshotReceiver; use cuprate_consensus::{ context::{ diff --git a/consensus/src/context/difficulty.rs b/consensus/src/context/difficulty.rs index b98f058a..055cd77b 100644 --- a/consensus/src/context/difficulty.rs +++ b/consensus/src/context/difficulty.rs @@ -3,9 +3,9 @@ use std::{collections::VecDeque, ops::Range}; use tower::ServiceExt; use tracing::instrument; -use crate::{ - helper::median, Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError, HardFork, -}; +use cuprate_helper::num::median; + +use crate::{Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError, HardFork}; /// The amount of blocks we account for to calculate difficulty const DIFFICULTY_WINDOW: usize = 720; diff --git a/consensus/src/context/hardforks.rs b/consensus/src/context/hardforks.rs index caf7c826..3f214ea8 100644 --- a/consensus/src/context/hardforks.rs +++ b/consensus/src/context/hardforks.rs @@ -79,9 +79,7 @@ impl HardForkState { let DatabaseResponse::BlockExtendedHeader(ext_header) = database .ready() .await? - .call(DatabaseRequest::BlockExtendedHeader( - (chain_height - 1).into(), - )) + .call(DatabaseRequest::BlockExtendedHeader(chain_height - 1)) .await? else { panic!("Database sent incorrect response!"); diff --git a/consensus/src/context/weight.rs b/consensus/src/context/weight.rs index bc39ad4e..73da0b19 100644 --- a/consensus/src/context/weight.rs +++ b/consensus/src/context/weight.rs @@ -16,12 +16,10 @@ use rayon::prelude::*; use tower::ServiceExt; use tracing::instrument; +use cuprate_helper::{asynch::rayon_spawn_async, num::median}; use monero_consensus::blocks::{penalty_free_zone, PENALTY_FREE_ZONE_5}; -use crate::{ - helper::{median, rayon_spawn_async}, - Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError, HardFork, -}; +use crate::{Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError, HardFork}; const SHORT_TERM_WINDOW: u64 = 100; const LONG_TERM_WINDOW: u64 = 100000; diff --git a/consensus/src/helper.rs b/consensus/src/helper.rs deleted file mode 100644 index 06fccf17..00000000 --- a/consensus/src/helper.rs +++ /dev/null @@ -1,44 +0,0 @@ -use std::ops::{Add, Div, Mul, Sub}; - -/// Spawns a task for the rayon thread pool and awaits the result without blocking the async runtime. -pub(crate) async fn rayon_spawn_async(f: F) -> R -where - F: FnOnce() -> R + Send + 'static, - R: Send + 'static, -{ - let (tx, rx) = tokio::sync::oneshot::channel(); - rayon::spawn(|| { - let _ = tx.send(f()); - }); - rx.await.expect("The sender must not be dropped") -} - -pub(crate) fn get_mid(a: T, b: T) -> T -where - T: Add + Sub + Div + Mul + Copy + From, -{ - let two: T = 2_u8.into(); - - // https://github.com/monero-project/monero/blob/90294f09ae34ef96f3dea5fea544816786df87c8/contrib/epee/include/misc_language.h#L43 - (a / two) + (b / two) + ((a - two * (a / two)) + (b - two * (b / two))) / two -} - -/// Gets the median from a sorted slice. -/// -/// If not sorted the output will be invalid. -pub(crate) fn median(array: &[T]) -> T -where - T: Add + Sub + Div + Mul + Copy + From, -{ - let mid = array.len() / 2; - - if array.len() == 1 { - return array[0]; - } - - if array.len() % 2 == 0 { - get_mid(array[mid - 1], array[mid]) - } else { - array[mid] - } -} diff --git a/consensus/src/lib.rs b/consensus/src/lib.rs index c30afada..dd848c13 100644 --- a/consensus/src/lib.rs +++ b/consensus/src/lib.rs @@ -6,11 +6,9 @@ use std::{ use monero_consensus::{transactions::OutputOnChain, ConsensusError, HardFork}; -//mod batch_verifier; mod batch_verifier; pub mod block; pub mod context; -mod helper; pub mod randomx; #[cfg(feature = "binaries")] pub mod rpc; @@ -115,7 +113,7 @@ pub struct ExtendedBlockHeader { #[derive(Debug, Clone)] pub enum DatabaseRequest { - BlockExtendedHeader(cuprate_common::BlockID), + BlockExtendedHeader(u64), BlockHash(u64), BlockExtendedHeaderInRange(std::ops::Range), diff --git a/consensus/src/rpc.rs b/consensus/src/rpc.rs index e8f8bffa..4978c03c 100644 --- a/consensus/src/rpc.rs +++ b/consensus/src/rpc.rs @@ -15,7 +15,9 @@ use futures::{ use tokio::sync::RwLock; use tower::{balance::p2c::Balance, ServiceExt}; -use crate::{helper::rayon_spawn_async, DatabaseRequest, DatabaseResponse}; +use cuprate_helper::asynch::rayon_spawn_async; + +use crate::{DatabaseRequest, DatabaseResponse}; pub mod cache; mod connection; diff --git a/consensus/src/rpc/connection.rs b/consensus/src/rpc/connection.rs index e0460c9a..7fd8707c 100644 --- a/consensus/src/rpc/connection.rs +++ b/consensus/src/rpc/connection.rs @@ -27,13 +27,10 @@ use tokio::{ use tower::Service; use tracing::{instrument, Instrument}; -use cuprate_common::{tower_utils::InfallibleOneshotReceiver, BlockID}; +use cuprate_helper::asynch::{rayon_spawn_async, InfallibleOneshotReceiver}; use super::ScanningCache; -use crate::{ - helper::rayon_spawn_async, DatabaseRequest, DatabaseResponse, ExtendedBlockHeader, HardFork, - OutputOnChain, -}; +use crate::{DatabaseRequest, DatabaseResponse, ExtendedBlockHeader, HardFork, OutputOnChain}; const DEFAULT_TIMEOUT: Duration = Duration::from_secs(300); const OUTPUTS_TIMEOUT: Duration = Duration::from_secs(50); @@ -98,36 +95,24 @@ impl RpcConnection { async fn get_extended_block_header( &self, - id: BlockID, + height: u64, ) -> Result { - tracing::info!("Retrieving block info with id: {}", id); + tracing::info!("Retrieving block info with height: {}", height); #[derive(Deserialize, Debug)] struct Response { block_header: BlockInfo, } - let info = match id { - BlockID::Height(height) => { - let res = self - .con - .json_rpc_call::( - "get_block_header_by_height", - Some(json!({"height": height})), - ) - .await?; - res.block_header - } - BlockID::Hash(hash) => { - let res = self - .con - .json_rpc_call::( - "get_block_header_by_hash", - Some(json!({"hash": hash})), - ) - .await?; - res.block_header - } + let info = { + let res = self + .con + .json_rpc_call::( + "get_block_header_by_height", + Some(json!({"height": height})), + ) + .await?; + res.block_header }; Ok(ExtendedBlockHeader { diff --git a/consensus/src/tests/context.rs b/consensus/src/tests/context.rs index 3fd10303..5756ea3f 100644 --- a/consensus/src/tests/context.rs +++ b/consensus/src/tests/context.rs @@ -2,11 +2,14 @@ use proptest::strategy::ValueTree; use proptest::{strategy::Strategy, test_runner::TestRunner}; use tower::ServiceExt; -use crate::context::{ - initialize_blockchain_context, BlockChainContextRequest, BlockChainContextResponse, - ContextConfig, UpdateBlockchainCacheData, +use crate::{ + context::{ + initialize_blockchain_context, BlockChainContextRequest, BlockChainContextResponse, + ContextConfig, UpdateBlockchainCacheData, + }, + tests::mock_db::*, + HardFork, }; -use crate::{tests::mock_db::*, HardFork}; pub(crate) mod data; mod difficulty; diff --git a/consensus/src/tests/context/difficulty.rs b/consensus/src/tests/context/difficulty.rs index b0a11b5f..0664ca80 100644 --- a/consensus/src/tests/context/difficulty.rs +++ b/consensus/src/tests/context/difficulty.rs @@ -2,7 +2,9 @@ use std::collections::VecDeque; use proptest::{arbitrary::any, prop_assert_eq, prop_compose, proptest}; -use crate::{context::difficulty::*, helper::median, tests::mock_db::*, HardFork}; +use cuprate_helper::num::median; + +use crate::{context::difficulty::*, tests::mock_db::*, HardFork}; const TEST_WINDOW: usize = 72; const TEST_CUT: usize = 6; diff --git a/consensus/src/tests/context/weight.rs b/consensus/src/tests/context/weight.rs index 12bb3c24..902d446a 100644 --- a/consensus/src/tests/context/weight.rs +++ b/consensus/src/tests/context/weight.rs @@ -4,8 +4,8 @@ use crate::{ BlockWeightsCacheConfig, }, tests::{context::data::BW_2850000_3050000, mock_db::*}, + HardFork, }; -use monero_consensus::HardFork; pub const TEST_WEIGHT_CONFIG: BlockWeightsCacheConfig = BlockWeightsCacheConfig::new(100, 5000); diff --git a/consensus/src/tests/mock_db.rs b/consensus/src/tests/mock_db.rs index 45a47636..d6e86f3a 100644 --- a/consensus/src/tests/mock_db.rs +++ b/consensus/src/tests/mock_db.rs @@ -15,8 +15,6 @@ use proptest::{ use proptest_derive::Arbitrary; use tower::{BoxError, Service}; -use cuprate_common::BlockID; - use crate::{DatabaseRequest, DatabaseResponse, ExtendedBlockHeader, HardFork}; prop_compose! { @@ -140,7 +138,7 @@ impl Service for DummyDatabase { async move { Ok(match req { - DatabaseRequest::BlockExtendedHeader(BlockID::Height(id)) => { + DatabaseRequest::BlockExtendedHeader(id) => { let mut id = usize::try_from(id).unwrap(); if let Some(dummy_height) = dummy_height { let block_len = blocks.read().unwrap().len(); diff --git a/consensus/src/transactions.rs b/consensus/src/transactions.rs index 8c019198..7396aa03 100644 --- a/consensus/src/transactions.rs +++ b/consensus/src/transactions.rs @@ -14,6 +14,7 @@ use rayon::prelude::*; use tower::{Service, ServiceExt}; use tracing::instrument; +use cuprate_helper::asynch::rayon_spawn_async; use monero_consensus::{ transactions::{ check_transaction_contextual, check_transaction_semantic, RingCTError, TransactionError, @@ -23,8 +24,8 @@ use monero_consensus::{ }; use crate::{ - batch_verifier::MultiThreadedBatchVerifier, context::ReOrgToken, helper::rayon_spawn_async, - Database, DatabaseRequest, DatabaseResponse, ExtendedConsensusError, + batch_verifier::MultiThreadedBatchVerifier, context::ReOrgToken, Database, DatabaseRequest, + DatabaseResponse, ExtendedConsensusError, }; mod contextual_data; diff --git a/cuprate/Cargo.toml b/cuprate/Cargo.toml deleted file mode 100644 index 9da30887..00000000 --- a/cuprate/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -name = "cuprate" -authors = [] -version = "0.1.0" -edition = "2021" - -[dependencies] -clap = "4" -serde = { version = "1", features = ["serde_derive"] } -thiserror = "1" - -[dependencies.abscissa_core] -version = "0.7.0" -# optional: use `gimli` to capture backtraces -# see https://github.com/rust-lang/backtrace-rs/issues/189 -# features = ["gimli-backtrace"] - -[dev-dependencies] -abscissa_core = { version = "0.7.0", features = ["testing"] } -once_cell = "1.2" - diff --git a/cuprate/README.md b/cuprate/README.md deleted file mode 100644 index 8ffe6a93..00000000 --- a/cuprate/README.md +++ /dev/null @@ -1,9 +0,0 @@ - -This application is authored using [Abscissa], a Rust application framework. - -For more information, see: - -[Documentation] - -[Abscissa]: https://github.com/iqlusioninc/abscissa -[Documentation]: https://docs.rs/abscissa_core/ diff --git a/cuprate/src/application.rs b/cuprate/src/application.rs deleted file mode 100644 index f4eb96b4..00000000 --- a/cuprate/src/application.rs +++ /dev/null @@ -1,88 +0,0 @@ -//! Cuprate Abscissa Application - -use crate::{commands::EntryPoint, config::CuprateConfig}; -use abscissa_core::{ - application::{self, AppCell}, - config::{self, CfgCell}, - trace, Application, FrameworkError, StandardPaths, -}; - -/// Application state -pub static APP: AppCell = AppCell::new(); - -/// Cuprate Application -#[derive(Debug)] -pub struct CuprateApp { - /// Application configuration. - config: CfgCell, - - /// Application state. - state: application::State, -} - -/// Initialize a new application instance. -/// -/// By default no configuration is loaded, and the framework state is -/// initialized to a default, empty state (no components, threads, etc). -impl Default for CuprateApp { - fn default() -> Self { - Self { - config: CfgCell::default(), - state: application::State::default(), - } - } -} - -impl Application for CuprateApp { - /// Entrypoint command for this application. - type Cmd = EntryPoint; - - /// Application configuration. - type Cfg = CuprateConfig; - - /// Paths to resources within the application. - type Paths = StandardPaths; - - /// Accessor for application configuration. - fn config(&self) -> config::Reader { - self.config.read() - } - - /// Borrow the application state immutably. - fn state(&self) -> &application::State { - &self.state - } - - /// Register all components used by this application. - /// - /// If you would like to add additional components to your application - /// beyond the default ones provided by the framework, this is the place - /// to do so. - fn register_components(&mut self, command: &Self::Cmd) -> Result<(), FrameworkError> { - let framework_components = self.framework_components(command)?; - let mut app_components = self.state.components_mut(); - app_components.register(framework_components) - } - - /// Post-configuration lifecycle callback. - /// - /// Called regardless of whether config is loaded to indicate this is the - /// time in app lifecycle when configuration would be loaded if - /// possible. - fn after_config(&mut self, config: Self::Cfg) -> Result<(), FrameworkError> { - // Configure components - let mut components = self.state.components_mut(); - components.after_config(&config)?; - self.config.set_once(config); - Ok(()) - } - - /// Get tracing configuration from command-line options - fn tracing_config(&self, command: &EntryPoint) -> trace::Config { - if command.verbose { - trace::Config::verbose() - } else { - trace::Config::default() - } - } -} diff --git a/cuprate/src/bin/cuprate/main.rs b/cuprate/src/bin/cuprate/main.rs deleted file mode 100644 index c349c179..00000000 --- a/cuprate/src/bin/cuprate/main.rs +++ /dev/null @@ -1,11 +0,0 @@ -//! Main entry point for Cuprate - -#![deny(warnings, missing_docs, trivial_casts, unused_qualifications)] -#![forbid(unsafe_code)] - -use cuprate::application::APP; - -/// Boot Cuprate -fn main() { - abscissa_core::boot(&APP); -} diff --git a/cuprate/src/commands.rs b/cuprate/src/commands.rs deleted file mode 100644 index 78ec2f6b..00000000 --- a/cuprate/src/commands.rs +++ /dev/null @@ -1,87 +0,0 @@ -//! Cuprate Subcommands -//! -//! This is where you specify the subcommands of your application. -//! -//! The default application comes with two subcommands: -//! -//! - `start`: launches the application -//! - `--version`: print application version -//! -//! See the `impl Configurable` below for how to specify the path to the -//! application's configuration file. - -mod start; - -use self::start::StartCmd; -use crate::config::CuprateConfig; -use abscissa_core::{config::Override, Command, Configurable, FrameworkError, Runnable}; -use std::path::PathBuf; - -/// Cuprate Configuration Filename -pub const CONFIG_FILE: &str = "cuprate.toml"; - -/// Cuprate Subcommands -/// Subcommands need to be listed in an enum. -#[derive(clap::Parser, Command, Debug, Runnable)] -pub enum CuprateCmd { - /// The `start` subcommand - Start(StartCmd), -} - -/// Entry point for the application. It needs to be a struct to allow using subcommands! -#[derive(clap::Parser, Command, Debug)] -#[command(author, about, version)] -pub struct EntryPoint { - #[command(subcommand)] - cmd: CuprateCmd, - - /// Enable verbose logging - #[arg(short, long)] - pub verbose: bool, - - /// Use the specified config file - #[arg(short, long)] - pub config: Option, -} - -impl Runnable for EntryPoint { - fn run(&self) { - self.cmd.run() - } -} - -/// This trait allows you to define how application configuration is loaded. -impl Configurable for EntryPoint { - /// Location of the configuration file - fn config_path(&self) -> Option { - // Check if the config file exists, and if it does not, ignore it. - // If you'd like for a missing configuration file to be a hard error - // instead, always return `Some(CONFIG_FILE)` here. - let filename = self - .config - .as_ref() - .map(PathBuf::from) - .unwrap_or_else(|| CONFIG_FILE.into()); - - if filename.exists() { - Some(filename) - } else { - None - } - } - - /// Apply changes to the config after it's been loaded, e.g. overriding - /// values in a config file using command-line options. - /// - /// This can be safely deleted if you don't want to override config - /// settings from command-line options. - fn process_config(&self, config: CuprateConfig) -> Result { - match &self.cmd { - CuprateCmd::Start(cmd) => cmd.override_config(config), - // - // If you don't need special overrides for some - // subcommands, you can just use a catch all - // _ => Ok(config), - } - } -} diff --git a/cuprate/src/commands/start.rs b/cuprate/src/commands/start.rs deleted file mode 100644 index 525e4b07..00000000 --- a/cuprate/src/commands/start.rs +++ /dev/null @@ -1,42 +0,0 @@ -//! `start` subcommand - example of how to write a subcommand - -/// App-local prelude includes `app_reader()`/`app_writer()`/`app_config()` -/// accessors along with logging macros. Customize as you see fit. -use crate::prelude::*; - -use crate::config::CuprateConfig; -use abscissa_core::{config, Command, FrameworkError, Runnable}; - -/// `start` subcommand -/// -/// The `Parser` proc macro generates an option parser based on the struct -/// definition, and is defined in the `clap` crate. See their documentation -/// for a more comprehensive example: -/// -/// -#[derive(clap::Parser, Command, Debug)] -pub struct StartCmd { - /// To whom are we saying hello? - recipient: Vec, -} - -impl Runnable for StartCmd { - /// Start the application. - fn run(&self) { - let config = APP.config(); - println!("Hello, {}!", &config.hello.recipient); - } -} - -impl config::Override for StartCmd { - // Process the given command line options, overriding settings from - // a configuration file using explicit flags taken from command-line - // arguments. - fn override_config(&self, mut config: CuprateConfig) -> Result { - if !self.recipient.is_empty() { - config.hello.recipient = self.recipient.join(" "); - } - - Ok(config) - } -} diff --git a/cuprate/src/config.rs b/cuprate/src/config.rs deleted file mode 100644 index 7fad4dac..00000000 --- a/cuprate/src/config.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Cuprate Config -//! -//! See instructions in `commands.rs` to specify the path to your -//! application's configuration file and/or command-line options -//! for specifying it. - -use serde::{Deserialize, Serialize}; - -/// Cuprate Configuration -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(deny_unknown_fields)] -pub struct CuprateConfig { - /// An example configuration section - pub hello: ExampleSection, -} - -/// Default configuration settings. -/// -/// Note: if your needs are as simple as below, you can -/// use `#[derive(Default)]` on CuprateConfig instead. -impl Default for CuprateConfig { - fn default() -> Self { - Self { - hello: ExampleSection::default(), - } - } -} - -/// Example configuration section. -/// -/// Delete this and replace it with your actual configuration structs. -#[derive(Clone, Debug, Deserialize, Serialize)] -#[serde(deny_unknown_fields)] -pub struct ExampleSection { - /// Example configuration value - pub recipient: String, -} - -impl Default for ExampleSection { - fn default() -> Self { - Self { - recipient: "world".to_owned(), - } - } -} diff --git a/cuprate/src/error.rs b/cuprate/src/error.rs deleted file mode 100644 index cdc847f7..00000000 --- a/cuprate/src/error.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! Error types - -use abscissa_core::error::{BoxError, Context}; -use std::{ - fmt::{self, Display}, - io, - ops::Deref, -}; -use thiserror::Error; - -/// Kinds of errors -#[derive(Copy, Clone, Debug, Eq, Error, PartialEq)] -pub enum ErrorKind { - /// Error in configuration file - #[error("config error")] - Config, - - /// Input/output error - #[error("I/O error")] - Io, -} - -impl ErrorKind { - /// Create an error context from this error - pub fn context(self, source: impl Into) -> Context { - Context::new(self, Some(source.into())) - } -} - -/// Error type -#[derive(Debug)] -pub struct Error(Box>); - -impl Deref for Error { - type Target = Context; - - fn deref(&self) -> &Context { - &self.0 - } -} - -impl Display for Error { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - self.0.fmt(f) - } -} - -impl std::error::Error for Error { - fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { - self.0.source() - } -} - -impl From for Error { - fn from(kind: ErrorKind) -> Self { - Context::new(kind, None).into() - } -} - -impl From> for Error { - fn from(context: Context) -> Self { - Error(Box::new(context)) - } -} - -impl From for Error { - fn from(err: io::Error) -> Self { - ErrorKind::Io.context(err).into() - } -} diff --git a/cuprate/src/lib.rs b/cuprate/src/lib.rs deleted file mode 100644 index 23bfc749..00000000 --- a/cuprate/src/lib.rs +++ /dev/null @@ -1,22 +0,0 @@ -//! Cuprate -//! -//! Application based on the [Abscissa] framework. -//! -//! [Abscissa]: https://github.com/iqlusioninc/abscissa - -// Tip: Deny warnings with `RUSTFLAGS="-D warnings"` environment variable in CI - -#![forbid(unsafe_code)] -#![warn( - missing_docs, - rust_2018_idioms, - trivial_casts, - unused_lifetimes, - unused_qualifications -)] - -pub mod application; -pub mod commands; -pub mod config; -pub mod error; -pub mod prelude; diff --git a/cuprate/src/prelude.rs b/cuprate/src/prelude.rs deleted file mode 100644 index 025040d7..00000000 --- a/cuprate/src/prelude.rs +++ /dev/null @@ -1,9 +0,0 @@ -//! Application-local prelude: conveniently import types/functions/macros -//! which are generally useful and should be available in every module with -//! `use crate::prelude::*; - -/// Abscissa core prelude -pub use abscissa_core::prelude::*; - -/// Application state -pub use crate::application::APP; diff --git a/cuprate/tests/acceptance.rs b/cuprate/tests/acceptance.rs deleted file mode 100644 index edfb1e0a..00000000 --- a/cuprate/tests/acceptance.rs +++ /dev/null @@ -1,91 +0,0 @@ -//! Acceptance test: runs the application as a subprocess and asserts its -//! output for given argument combinations matches what is expected. -//! -//! Modify and/or delete these as you see fit to test the specific needs of -//! your application. -//! -//! For more information, see: -//! - -// Tip: Deny warnings with `RUSTFLAGS="-D warnings"` environment variable in CI - -#![forbid(unsafe_code)] -#![warn( - missing_docs, - rust_2018_idioms, - trivial_casts, - unused_lifetimes, - unused_qualifications -)] - -use abscissa_core::testing::prelude::*; -use cuprate::config::CuprateConfig; -use once_cell::sync::Lazy; - -/// Executes your application binary via `cargo run`. -/// -/// Storing this value as a [`Lazy`] static ensures that all instances of -/// the runner acquire a mutex when executing commands and inspecting -/// exit statuses, serializing what would otherwise be multithreaded -/// invocations as `cargo test` executes tests in parallel by default. -pub static RUNNER: Lazy = Lazy::new(|| CmdRunner::default()); - -/// Use `CuprateConfig::default()` value if no config or args -#[test] -fn start_no_args() { - let mut runner = RUNNER.clone(); - let mut cmd = runner.arg("start").capture_stdout().run(); - cmd.stdout().expect_line("Hello, world!"); - cmd.wait().unwrap().expect_success(); -} - -/// Use command-line argument value -#[test] -fn start_with_args() { - let mut runner = RUNNER.clone(); - let mut cmd = runner - .args(&["start", "acceptance", "test"]) - .capture_stdout() - .run(); - - cmd.stdout().expect_line("Hello, acceptance test!"); - cmd.wait().unwrap().expect_success(); -} - -/// Use configured value -#[test] -fn start_with_config_no_args() { - let mut config = CuprateConfig::default(); - config.hello.recipient = "configured recipient".to_owned(); - let expected_line = format!("Hello, {}!", &config.hello.recipient); - - let mut runner = RUNNER.clone(); - let mut cmd = runner.config(&config).arg("start").capture_stdout().run(); - cmd.stdout().expect_line(&expected_line); - cmd.wait().unwrap().expect_success(); -} - -/// Override configured value with command-line argument -#[test] -fn start_with_config_and_args() { - let mut config = CuprateConfig::default(); - config.hello.recipient = "configured recipient".to_owned(); - - let mut runner = RUNNER.clone(); - let mut cmd = runner - .config(&config) - .args(&["start", "acceptance", "test"]) - .capture_stdout() - .run(); - - cmd.stdout().expect_line("Hello, acceptance test!"); - cmd.wait().unwrap().expect_success(); -} - -/// Example of a test which matches a regular expression -#[test] -fn version_no_args() { - let mut runner = RUNNER.clone(); - let mut cmd = runner.arg("--version").capture_stdout().run(); - cmd.stdout().expect_regex(r"\A\w+ [\d\.\-]+\z"); -} diff --git a/helper/Cargo.toml b/helper/Cargo.toml index 465e9518..d74ca1c5 100644 --- a/helper/Cargo.toml +++ b/helper/Cargo.toml @@ -1,7 +1,12 @@ [package] -name = "helper" +name = "cuprate-helper" version = "0.1.0" edition = "2021" +description = "Helper functions used around Cuprate." +license = "MIT" +authors = ["hinto-janai ", "Boog900"] +repository = "https://github.com/Cuprate/cuprate/tree/main/consensus" + [features] # All features on by default. diff --git a/helper/src/lib.rs b/helper/src/lib.rs index e52e0c67..fe118bb2 100644 --- a/helper/src/lib.rs +++ b/helper/src/lib.rs @@ -38,6 +38,7 @@ pub mod asynch; // async collides #[cfg(feature = "atomic")] pub mod atomic; +pub mod network; #[cfg(feature = "num")] pub mod num; #[cfg(feature = "thread")] diff --git a/common/src/network.rs b/helper/src/network.rs similarity index 63% rename from common/src/network.rs rename to helper/src/network.rs index 81f17a6c..684e71a4 100644 --- a/common/src/network.rs +++ b/helper/src/network.rs @@ -1,3 +1,11 @@ +//! This module contains an enum representing every Monero network: mainnet, testnet, stagenet and functionality +//! related to that. +//! +//! This feels out of place for the helper crate but this is needed through out Cuprate and felt too small to split +//! into it's own crate. +//! +//! `#[no_std]` compatible. + const MAINNET_NETWORK_ID: [u8; 16] = [ 0x12, 0x30, 0xF1, 0x71, 0x61, 0x04, 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x10, ]; @@ -8,15 +16,20 @@ const STAGENET_NETWORK_ID: [u8; 16] = [ 0x12, 0x30, 0xF1, 0x71, 0x61, 0x04, 0x41, 0x61, 0x17, 0x31, 0x00, 0x82, 0x16, 0xA1, 0xA1, 0x12, ]; +/// An enum representing every Monero network. #[derive(Debug, Clone, Copy, Default)] pub enum Network { + /// Mainnet #[default] Mainnet, + /// Testnet Testnet, + /// Stagenet Stagenet, } impl Network { + /// Returns the network ID for the current network. pub fn network_id(&self) -> [u8; 16] { match self { Network::Mainnet => MAINNET_NETWORK_ID, diff --git a/helper/src/num.rs b/helper/src/num.rs index a4aedcfa..34dd1fc5 100644 --- a/helper/src/num.rs +++ b/helper/src/num.rs @@ -52,7 +52,7 @@ impl_float!(f32, f64); /// Returns the average of two numbers; works with at least all integral and floating point types /// /// ```rust -/// # use helper::num::*; +/// # use cuprate_helper::num::*; /// assert_eq!(get_mid(0, 10), 5); /// assert_eq!(get_mid(0.0, 10.0), 5.0); /// assert_eq!(get_mid(-10.0, 10.0), 0.0); @@ -76,7 +76,7 @@ where /// Gets the median from a sorted slice. /// /// ```rust -/// # use helper::num::*; +/// # use cuprate_helper::num::*; /// let mut vec = vec![10, 5, 1, 4, 2, 8, 9, 7, 3, 6]; /// vec.sort(); /// @@ -109,7 +109,7 @@ where /// Compare 2 non-`NaN` floats. /// /// ```rust -/// # use helper::num::*; +/// # use cuprate_helper::num::*; /// # use core::cmp::Ordering; /// assert_eq!(cmp_float(0.0, 1.0), Ordering::Less); /// assert_eq!(cmp_float(1.0, 1.0), Ordering::Equal); @@ -128,7 +128,7 @@ where /// This function panics if either floats are NaNs. /// /// ```rust,should_panic -/// # use helper::num::*; +/// # use cuprate_helper::num::*; /// cmp_float(0.0, f32::NAN); /// ``` pub fn cmp_float(a: F, b: F) -> Ordering { @@ -144,7 +144,7 @@ pub fn cmp_float(a: F, b: F) -> Ordering { /// Compare 2 floats, `NaN`'s will always return [`Ordering::Equal`]. /// /// ```rust -/// # use helper::num::*; +/// # use cuprate_helper::num::*; /// # use core::cmp::Ordering; /// assert_eq!(cmp_float_nan(0.0, 1.0), Ordering::Less); /// assert_eq!(cmp_float_nan(1.0, 1.0), Ordering::Equal); diff --git a/net/monero-wire/Cargo.toml b/net/monero-wire/Cargo.toml index 3413b927..a654061a 100644 --- a/net/monero-wire/Cargo.toml +++ b/net/monero-wire/Cargo.toml @@ -9,11 +9,11 @@ repository = "https://github.com/SyntheticBird45/cuprate/tree/main/net/monero-wi [dependencies] levin-cuprate = {path="../levin"} -monero-epee-bin-serde = {git = "https://github.com/monero-rs/monero-epee-bin-serde.git", rev="aafe4ba"} -serde = {version = "1", features = ["derive"]} -serde_bytes = "0.11" -thiserror = "1" +monero-epee-bin-serde = { workspace = true, features = ["container_as_blob"] } +serde = { workspace = true, features = ["derive", "std"]} +serde_bytes = { workspace = true, features = ["std"]} +thiserror = { workspace = true } [dev-dependencies] -hex = "0.4.3" +hex = { workspace = true, features = ["std"]} diff --git a/p2p/address-book/Cargo.toml b/p2p/address-book/Cargo.toml index 70ffcf06..9ebbf629 100644 --- a/p2p/address-book/Cargo.toml +++ b/p2p/address-book/Cargo.toml @@ -7,9 +7,9 @@ authors = ["Boog900"] [dependencies] -cuprate-common = {path = "../../common"} -monero-wire = {path= "../../net/monero-wire"} -monero-p2p = {path = "../monero-p2p" } +monero-pruning = { path = "../../pruning" } +monero-wire = { path= "../../net/monero-wire" } +monero-p2p = { path = "../monero-p2p" } tower = { workspace = true, features = ["util", "buffer"] } tokio = { workspace = true, features = ["time", "fs", "rt"]} diff --git a/p2p/address-book/src/book.rs b/p2p/address-book/src/book.rs index 22cc7a66..211bacaf 100644 --- a/p2p/address-book/src/book.rs +++ b/p2p/address-book/src/book.rs @@ -19,13 +19,13 @@ use tokio::{ }; use tower::Service; -use cuprate_common::PruningSeed; use monero_p2p::{ client::InternalPeerID, handles::ConnectionHandle, services::{AddressBookRequest, AddressBookResponse, ZoneSpecificPeerListEntryBase}, NetZoneAddress, NetworkZone, }; +use monero_pruning::PruningSeed; use crate::{peer_list::PeerList, store::save_peers_to_disk, AddressBookError, Config}; diff --git a/p2p/address-book/src/book/tests.rs b/p2p/address-book/src/book/tests.rs index d6df95bd..7a443d79 100644 --- a/p2p/address-book/src/book/tests.rs +++ b/p2p/address-book/src/book/tests.rs @@ -4,8 +4,8 @@ use futures::StreamExt; use tokio::sync::Semaphore; use tokio::time::interval; -use cuprate_common::PruningSeed; use monero_p2p::handles::HandleBuilder; +use monero_pruning::PruningSeed; use super::{AddressBook, ConnectionPeerEntry, InternalPeerID}; use crate::{peer_list::tests::make_fake_peer_list, AddressBookError, Config}; diff --git a/p2p/address-book/src/peer_list.rs b/p2p/address-book/src/peer_list.rs index d48ed35d..8e9d5b8d 100644 --- a/p2p/address-book/src/peer_list.rs +++ b/p2p/address-book/src/peer_list.rs @@ -2,8 +2,8 @@ use std::collections::{BTreeMap, HashMap, HashSet}; use rand::{seq::SliceRandom, Rng}; -use cuprate_common::{PruningSeed, CRYPTONOTE_MAX_BLOCK_NUMBER}; use monero_p2p::{services::ZoneSpecificPeerListEntryBase, NetZoneAddress, NetworkZone}; +use monero_pruning::{PruningSeed, CRYPTONOTE_MAX_BLOCK_NUMBER}; #[cfg(test)] pub mod tests; diff --git a/p2p/address-book/src/peer_list/tests.rs b/p2p/address-book/src/peer_list/tests.rs index e732246a..70177686 100644 --- a/p2p/address-book/src/peer_list/tests.rs +++ b/p2p/address-book/src/peer_list/tests.rs @@ -2,8 +2,8 @@ use std::collections::HashSet; use rand::Rng; -use cuprate_common::PruningSeed; use monero_p2p::services::ZoneSpecificPeerListEntryBase; +use monero_pruning::PruningSeed; use cuprate_test_utils::test_netzone::{TestNetZone, TestNetZoneAddr}; use monero_p2p::NetZoneAddress; diff --git a/p2p/monero-p2p/Cargo.toml b/p2p/monero-p2p/Cargo.toml index 779a22d5..14f2f192 100644 --- a/p2p/monero-p2p/Cargo.toml +++ b/p2p/monero-p2p/Cargo.toml @@ -7,11 +7,12 @@ authors = ["Boog900"] [features] default = ["borsh"] -borsh = ["dep:borsh"] +borsh = ["dep:borsh", "monero-pruning/borsh"] [dependencies] -monero-wire = {path= "../../net/monero-wire"} -cuprate-common = {path = "../../common", features = ["borsh"]} +cuprate-helper = { path = "../../helper" } +monero-wire = { path = "../../net/monero-wire" } +monero-pruning = { path = "../../pruning" } tokio = { workspace = true, features = ["net", "sync", "macros"]} tokio-util = { workspace = true, features = ["codec"] } diff --git a/p2p/monero-p2p/src/client.rs b/p2p/monero-p2p/src/client.rs index dca66e2f..5df55823 100644 --- a/p2p/monero-p2p/src/client.rs +++ b/p2p/monero-p2p/src/client.rs @@ -9,7 +9,7 @@ use tokio::{sync::mpsc, task::JoinHandle}; use tokio_util::sync::PollSender; use tower::Service; -use cuprate_common::tower_utils::InfallibleOneshotReceiver; +use cuprate_helper::asynch::InfallibleOneshotReceiver; use crate::{ handles::ConnectionHandle, NetworkZone, PeerError, PeerRequest, PeerResponse, SharedError, diff --git a/p2p/monero-p2p/src/services.rs b/p2p/monero-p2p/src/services.rs index 9a1a254e..c09ca26d 100644 --- a/p2p/monero-p2p/src/services.rs +++ b/p2p/monero-p2p/src/services.rs @@ -1,4 +1,4 @@ -use cuprate_common::{PruningError, PruningSeed}; +use monero_pruning::{PruningError, PruningSeed}; use monero_wire::{NetZone, NetworkAddress, PeerListEntryBase}; use crate::{ diff --git a/p2p/monero-p2p/tests/handshake.rs b/p2p/monero-p2p/tests/handshake.rs index 51f32558..fb53ac60 100644 --- a/p2p/monero-p2p/tests/handshake.rs +++ b/p2p/monero-p2p/tests/handshake.rs @@ -5,7 +5,7 @@ use futures::{channel::mpsc, StreamExt}; use tokio::sync::{broadcast, Semaphore}; use tower::{Service, ServiceExt}; -use cuprate_common::Network; +use cuprate_helper::network::Network; use monero_wire::{common::PeerSupportFlags, BasicNodeData}; use monero_p2p::{ diff --git a/pruning/Cargo.toml b/pruning/Cargo.toml new file mode 100644 index 00000000..fbd559e9 --- /dev/null +++ b/pruning/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "monero-pruning" +version = "0.1.0" +edition = "2021" + +[features] +default = [] +borsh = ["dep:borsh"] + +[dependencies] +thiserror = { workspace = true } + +borsh = { workspace = true, features = ["derive", "std"], optional = true } diff --git a/common/src/pruning.rs b/pruning/src/lib.rs similarity index 96% rename from common/src/pruning.rs rename to pruning/src/lib.rs index aa1cb67e..19cc8a15 100644 --- a/common/src/pruning.rs +++ b/pruning/src/lib.rs @@ -1,6 +1,6 @@ //! # Pruning Mechanism for Monero //! -//! This module provides an implementation of the pruning mechanism used in Monero. +//! This crate provides an implementation of the pruning mechanism used in Monero. //! The main data structure, `PruningSeed`, encapsulates the logic for creating and manipulating pruning seeds, //! which determine the set of blocks to be pruned from the blockchain. //! @@ -8,9 +8,9 @@ //! split into 8 parts): //! //! ```rust -//! use cuprate_common::pruning::PruningSeed; +//! use monero_pruning::PruningSeed; //! -//! let seed: u32 = 386; // the seed you wan't to check is valid +//! let seed: u32 = 386; // the seed you want to check is valid //! match PruningSeed::try_from(seed) { //! Ok(seed) => seed, // seed is valid //! Err(e) => panic!("seed is invalid") @@ -22,10 +22,11 @@ use std::cmp::Ordering; use thiserror::Error; -use super::{ - CRYPTONOTE_MAX_BLOCK_NUMBER, CRYPTONOTE_PRUNING_LOG_STRIPES, CRYPTONOTE_PRUNING_STRIPE_SIZE, - CRYPTONOTE_PRUNING_TIP_BLOCKS, -}; +pub const CRYPTONOTE_MAX_BLOCK_NUMBER: u64 = 500000000; + +pub const CRYPTONOTE_PRUNING_LOG_STRIPES: u32 = 3; +pub const CRYPTONOTE_PRUNING_STRIPE_SIZE: u64 = 4096; +pub const CRYPTONOTE_PRUNING_TIP_BLOCKS: u64 = 5500; const PRUNING_SEED_LOG_STRIPES_SHIFT: u32 = 7; const PRUNING_SEED_STRIPE_SHIFT: u32 = 0; @@ -185,7 +186,7 @@ impl PruningSeed { 1 }; - // amt_of_cycles * blocks in a cycle + how many blocks through a cycles until the seed starts storing blocks + // amt_of_cycles * blocks in a cycle + how many blocks through a cycles until the seed starts storing blocks let calculated_height = cycles_start * (CRYPTONOTE_PRUNING_STRIPE_SIZE << seed_log_stripes) + (seed_stripe as u64 - 1) * CRYPTONOTE_PRUNING_STRIPE_SIZE; @@ -289,9 +290,7 @@ fn get_block_pruning_stripe( #[cfg(test)] mod tests { - use crate::pruning::{get_block_pruning_stripe, PruningSeed}; - - use super::CRYPTONOTE_PRUNING_LOG_STRIPES; + use super::*; fn make_all_pruning_seeds() -> Vec { let possible_stripes = 1..(1 << CRYPTONOTE_PRUNING_LOG_STRIPES);