Explorar o código

minerd: mining benchmark added to get system hashrate

skoupidi hai 8 meses
pai
achega
2d5c9371e6

+ 3 - 0
bin/minerd/minerd.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 #threads = 4
 #threads = 4
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 89 - 0
bin/minerd/src/benchmark.rs

@@ -0,0 +1,89 @@
+/* This file is part of DarkFi (https://dark.fi)
+ *
+ * Copyright (C) 2020-2025 Dyne.org foundation
+ *
+ * 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 <https://www.gnu.org/licenses/>.
+ */
+
+use std::{str::FromStr, thread, time::Instant};
+
+use tracing::{error, info};
+
+use darkfi::{
+    blockchain::{Header, HeaderHash},
+    util::time::Timestamp,
+    validator::pow::generate_mining_vms,
+    Result,
+};
+
+/// Performs provided number of nonces simulating mining for provided
+/// threads count to determine system hashrate.
+pub fn benchmark(threads: usize, nonces: u64) -> Result<()> {
+    // Check provided params are valid
+    if threads == 0 {
+        error!(target: "minerd::benchmark", "No threads were configured!");
+        return Ok(())
+    }
+
+    if nonces == 0 {
+        error!(target: "minerd::benchmark", "No number of nonces was configured!");
+        return Ok(())
+    }
+    info!(target: "minerd::benchmark", "Starting DarkFi hashrate benchmark for {threads} threads and {nonces} nonces");
+
+    // Setup VMs using a dummy key for reproducible results
+    let key =
+        HeaderHash::from_str("c09967802bab1a95a4c434f18beb5a79e68ec7c75b252eb47e56516f32db8ce1")?;
+    info!(target: "minerd::benchmark", "Initializing {threads} VMs for key: {key}");
+    let (_, recvr) = smol::channel::bounded(1);
+    let vms = generate_mining_vms(&key, threads, &recvr)?;
+
+    // Use a dummy header to mine for reproducible results
+    let header = Header::new(key, 1, Timestamp::from_u64(1765378623), 0);
+
+    // Start mining
+    info!(target: "minerd::benchmark", "Starting mining threads...");
+    let mut handles = Vec::with_capacity(vms.len());
+    let threads = vms.len() as u64;
+    let mining_start = Instant::now();
+    for t in 0..threads {
+        let vm = vms[t as usize].clone();
+        let mut thread_header = header.clone();
+        thread_header.nonce = t;
+
+        handles.push(thread::spawn(move || {
+            while thread_header.nonce < nonces {
+                let _ = vm.calculate_hash(thread_header.hash().inner());
+                // This means thread 0 will use nonces, 0, 4, 8, ...
+                // and thread 1 will use nonces, 1, 5, 9, ...
+                thread_header.nonce += threads;
+            }
+        }));
+    }
+
+    // Wait for threads to finish mining
+    for handle in handles {
+        let _ = handle.join();
+    }
+
+    // Print total results
+    let elapsed = mining_start.elapsed();
+    let hashrate = if elapsed.as_secs_f64() == 0.0 {
+        nonces as f64 * 1000.0 / elapsed.as_millis() as f64
+    } else {
+        nonces as f64 / elapsed.as_secs_f64()
+    };
+    info!(target: "minerd::benchmark", "Threads completed {nonces} nonces in {elapsed:?} with hashrate: {hashrate:.2} h/s");
+    Ok(())
+}

+ 3 - 0
bin/minerd/src/lib.rs

@@ -32,6 +32,9 @@ use darkfi::{
 };
 };
 use darkfi_sdk::crypto::Keypair;
 use darkfi_sdk::crypto::Keypair;
 
 
+/// Miner benchmarking related methods
+pub mod benchmark;
+
 /// darkfid JSON-RPC related methods
 /// darkfid JSON-RPC related methods
 mod rpc;
 mod rpc;
 use rpc::{polling_task, DarkfidRpcClient};
 use rpc::{polling_task, DarkfidRpcClient};

+ 10 - 1
bin/minerd/src/main.rs

@@ -32,7 +32,7 @@ use darkfi_sdk::{
     pasta::pallas,
     pasta::pallas,
 };
 };
 
 
-use minerd::{MinerNodeConfig, Minerd};
+use minerd::{benchmark::benchmark, MinerNodeConfig, Minerd};
 
 
 const CONFIG_FILE: &str = "minerd.toml";
 const CONFIG_FILE: &str = "minerd.toml";
 const CONFIG_FILE_CONTENTS: &str = include_str!("../minerd.toml");
 const CONFIG_FILE_CONTENTS: &str = include_str!("../minerd.toml");
@@ -49,6 +49,10 @@ struct Args {
     /// PoW miner number of threads to use
     /// PoW miner number of threads to use
     threads: usize,
     threads: usize,
 
 
+    #[structopt(short, long)]
+    /// Number of nonces to execute in system hashrate benchmark
+    bench: Option<u64>,
+
     #[structopt(short, long, default_value = "2")]
     #[structopt(short, long, default_value = "2")]
     /// Polling rate to ask darkfid for mining jobs
     /// Polling rate to ask darkfid for mining jobs
     polling_rate: u64,
     polling_rate: u64,
@@ -140,6 +144,11 @@ pub async fn parse_blockchain_config(
 
 
 async_daemonize!(realmain);
 async_daemonize!(realmain);
 async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
 async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
+    // Run system hashrate benchmark if requested
+    if let Some(nonces) = args.bench {
+        return benchmark(args.threads, nonces)
+    }
+
     info!(target: "minerd", "Starting DarkFi Mining Daemon...");
     info!(target: "minerd", "Starting DarkFi Mining Daemon...");
 
 
     // Grab blockchain network configuration
     // Grab blockchain network configuration

+ 3 - 0
contrib/localnet/darkfid-five-nodes/minerd0.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 threads = 1
 threads = 1
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/minerd1.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 threads = 1
 threads = 1
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/minerd2.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 threads = 1
 threads = 1
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/minerd3.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 threads = 1
 threads = 1
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 3 - 0
contrib/localnet/darkfid-five-nodes/minerd4.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 threads = 1
 threads = 1
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 3 - 0
contrib/localnet/darkfid-single-node/minerd.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 #threads = 4
 #threads = 4
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 3 - 0
contrib/localnet/darkfid-small/minerd0.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 threads = 2
 threads = 2
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2
 
 

+ 3 - 0
contrib/localnet/darkfid-small/minerd1.toml

@@ -9,6 +9,9 @@
 # PoW miner number of threads to use
 # PoW miner number of threads to use
 threads = 2
 threads = 2
 
 
+# Number of nonces to execute in system hashrate benchmark
+#bench = 1000
+
 # Polling rate to ask darkfid for mining jobs
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 #polling_rate = 2