From 1702caa63c2d6a276f808ef9775649c64189b28e Mon Sep 17 00:00:00 2001 From: sword_smith Date: Tue, 1 Oct 2024 17:47:26 +0200 Subject: [PATCH] feat: Add estimate of machine power to `networking_state` Estimate which kind of proofs the host-machine is capable of generating: LockScript (very cheap), ProofCollection (possible on regular computers), SingleProof (only possible on very powerful machines). What to do with transactions before sending them to peers or inserting them into the mempool will be determined based on this parameter. Co-authored-by: Alan Szepieniec --- Cargo.lock | 81 ++++++++++++++++++++++- Cargo.toml | 1 + src/config_models/cli_args.rs | 6 ++ src/lib.rs | 7 +- src/models/state/networking_state.rs | 44 +++++++++++- src/models/state/tx_proving_capability.rs | 27 ++++++++ src/tests/shared.rs | 2 +- 7 files changed, 163 insertions(+), 5 deletions(-) create mode 100644 src/models/state/tx_proving_capability.rs 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