diff --git a/Cargo.lock b/Cargo.lock index af15f0421..bb805682c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1300,7 +1300,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.52.0", ] [[package]] @@ -1641,6 +1641,7 @@ dependencies = [ "sha3", "strum 0.26.3", "strum_macros 0.26.4", + "sysinfo", "systemstat", "tarpc", "tasm-lib", @@ -1668,6 +1669,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "nu-ansi-term" version = "0.46.0" @@ -2697,6 +2707,20 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sysinfo" +version = "0.31.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" +dependencies = [ + "core-foundation-sys", + "libc", + "memchr", + "ntapi", + "rayon", + "windows", +] + [[package]] name = "systemstat" version = "0.2.3" @@ -2756,7 +2780,7 @@ dependencies = [ "const_format", "derive_tasm_object", "hex", - "itertools 0.10.5", + "itertools 0.13.0", "ndarray", "num", "num-traits", @@ -3490,6 +3514,16 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12342cb4d8e3b046f3d80effd474a7a02447231330ef77d71daa6fbc40681143" +dependencies = [ + "windows-core 0.57.0", + "windows-targets 0.52.6", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -3499,6 +3533,49 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ed2439a290666cd67ecce2b0ffaad89c2a56b976b736e6ece670297897832d" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-result", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-implement" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "windows-interface" +version = "0.57.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.72", +] + +[[package]] +name = "windows-result" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e383302e8ec8515204254685643de10811af0ed97ea37210dc26fb0032647f8" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index aa4502f1b..66151f306 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -65,6 +65,7 @@ sha3 = "0.10.8" readonly = "0.2.12" thiserror = "1.0.59" systemstat = "0.2.3" +sysinfo = "0.31.4" [dev-dependencies] test-strategy = "0.3" diff --git a/src/config_models/cli_args.rs b/src/config_models/cli_args.rs index e158c4f0a..bfa5d13b9 100644 --- a/src/config_models/cli_args.rs +++ b/src/config_models/cli_args.rs @@ -7,6 +7,7 @@ use clap::builder::RangedI64ValueParser; use clap::Parser; use super::network::Network; +use crate::models::state::tx_proving_capability::TxProvingCapability; /// The `neptune-core` command-line program starts a Neptune node. #[derive(Parser, Debug, Clone)] @@ -127,6 +128,11 @@ pub struct Args { #[clap(long, default_value = "false")] pub privacy: bool, + /// Configure how complicated proofs this machine is capable of producing. + /// If no value is set, this parameter is estimated. + #[clap(long)] + pub tx_proving_capability: Option, + /// Enable tokio tracing for consumption by the tokio-console application /// note: this will attempt to connect to localhost:6669 #[structopt(long, name = "tokio-console", default_value = "false")] diff --git a/src/lib.rs b/src/lib.rs index bcad56f87..1a8f22c60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -142,7 +142,12 @@ pub async fn initialize(cli_args: cli_args::Args) -> Result<()> { // Create handshake data which is used when connecting to outgoing peers specified in the // CLI arguments let syncing = false; - let networking_state = NetworkingState::new(peer_map, peer_databases, syncing); + let networking_state = NetworkingState::new( + peer_map, + peer_databases, + syncing, + cli_args.tx_proving_capability, + ); let light_state: LightState = LightState::from(latest_block.clone()); let blockchain_archival_state = BlockchainArchivalState { diff --git a/src/models/state/networking_state.rs b/src/models/state/networking_state.rs index 2d5ebd277..59d304abc 100644 --- a/src/models/state/networking_state.rs +++ b/src/models/state/networking_state.rs @@ -3,7 +3,10 @@ use std::net::IpAddr; use std::net::SocketAddr; use anyhow::Result; +use num_traits::Zero; +use sysinfo::System; +use super::tx_proving_capability::TxProvingCapability; use crate::config_models::data_directory::DataDirectory; use crate::database::create_db_if_missing; use crate::database::NeptuneLevelDb; @@ -35,15 +38,54 @@ pub struct NetworkingState { // Read-only value set during startup pub instance_id: u128, + + /// The capabilities of this machine to produce STARK proofs + pub tx_proving_capability: TxProvingCapability, } impl NetworkingState { - pub fn new(peer_map: PeerMap, peer_databases: PeerDatabases, syncing: bool) -> Self { + pub(crate) fn new( + peer_map: PeerMap, + peer_databases: PeerDatabases, + syncing: bool, + tx_proving_capability: Option, + ) -> Self { + println!("{tx_proving_capability:?}"); + let tx_proving_capability = + tx_proving_capability.unwrap_or_else(Self::estimate_proving_power); + println!("{tx_proving_capability:?}"); Self { peer_map, peer_databases, syncing, instance_id: rand::random(), + tx_proving_capability, + } + } + + pub(crate) fn estimate_proving_power() -> TxProvingCapability { + const SINGLE_PROOF_CORE_REQ: usize = 19; + const SINGLE_PROOF_MEMORY_USAGE: u64 = (1u64 << 30) * 128; + const PROOF_COLLECTION_CORE_REQ: usize = 2; + const PROOF_COLLECTION_MEMORY_USAGE: u64 = (1u64 << 30) * 16; + + let s = System::new_all(); + let total_memory = s.total_memory(); + assert!( + !total_memory.is_zero(), + "Total memory reported illegal value of 0" + ); + + let physical_core_count = s.physical_core_count().unwrap_or(1); + + if total_memory > SINGLE_PROOF_MEMORY_USAGE && physical_core_count > SINGLE_PROOF_CORE_REQ { + TxProvingCapability::SingleProof + } else if total_memory > PROOF_COLLECTION_MEMORY_USAGE + && physical_core_count > PROOF_COLLECTION_CORE_REQ + { + TxProvingCapability::ProofCollection + } else { + TxProvingCapability::LockScript } } diff --git a/src/models/state/tx_proving_capability.rs b/src/models/state/tx_proving_capability.rs new file mode 100644 index 000000000..9d97dca03 --- /dev/null +++ b/src/models/state/tx_proving_capability.rs @@ -0,0 +1,27 @@ +use std::str::FromStr; + +use clap::error::ErrorKind; +use clap::Parser; + +#[derive(Parser, Debug, Clone, Copy)] +pub enum TxProvingCapability { + LockScript, + ProofCollection, + SingleProof, +} + +impl FromStr for TxProvingCapability { + type Err = clap::Error; + + fn from_str(s: &str) -> Result { + match s { + "lockscript" => Ok(TxProvingCapability::LockScript), + "proofcollection" => Ok(TxProvingCapability::ProofCollection), + "singleproof" => Ok(TxProvingCapability::SingleProof), + _ => Err(clap::Error::raw( + ErrorKind::InvalidValue, + "Invalid machine proving power", + )), + } + } +} diff --git a/src/tests/shared.rs b/src/tests/shared.rs index 90e7bdbe5..387a2d3fe 100644 --- a/src/tests/shared.rs +++ b/src/tests/shared.rs @@ -188,7 +188,7 @@ pub async fn mock_genesis_global_state( std::net::SocketAddr::from_str(&format!("123.123.123.{}:8080", i)).unwrap(); peer_map.insert(peer_address, get_dummy_peer(peer_address)); } - let networking_state = NetworkingState::new(peer_map, peer_db, syncing); + let networking_state = NetworkingState::new(peer_map, peer_db, syncing, None); let genesis_block = archival_state.get_tip().await; // Sanity check