From 2d5c9371e6be38306bb6b471f50b8a4731949c77 Mon Sep 17 00:00:00 2001 From: skoupidi Date: Wed, 10 Dec 2025 17:30:01 +0200 Subject: [PATCH] minerd: mining benchmark added to get system hashrate --- bin/minerd/minerd.toml | 3 + bin/minerd/src/benchmark.rs | 89 +++++++++++++++++++ bin/minerd/src/lib.rs | 3 + bin/minerd/src/main.rs | 11 ++- .../localnet/darkfid-five-nodes/minerd0.toml | 3 + .../localnet/darkfid-five-nodes/minerd1.toml | 3 + .../localnet/darkfid-five-nodes/minerd2.toml | 3 + .../localnet/darkfid-five-nodes/minerd3.toml | 3 + .../localnet/darkfid-five-nodes/minerd4.toml | 3 + .../localnet/darkfid-single-node/minerd.toml | 3 + contrib/localnet/darkfid-small/minerd0.toml | 3 + contrib/localnet/darkfid-small/minerd1.toml | 3 + 12 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 bin/minerd/src/benchmark.rs diff --git a/bin/minerd/minerd.toml b/bin/minerd/minerd.toml index 661eab54e..b0964ab02 100644 --- a/bin/minerd/minerd.toml +++ b/bin/minerd/minerd.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use #threads = 4 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/bin/minerd/src/benchmark.rs b/bin/minerd/src/benchmark.rs new file mode 100644 index 000000000..f905d21d8 --- /dev/null +++ b/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 . + */ + +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(()) +} diff --git a/bin/minerd/src/lib.rs b/bin/minerd/src/lib.rs index 295327f89..4affc2f7e 100644 --- a/bin/minerd/src/lib.rs +++ b/bin/minerd/src/lib.rs @@ -32,6 +32,9 @@ use darkfi::{ }; use darkfi_sdk::crypto::Keypair; +/// Miner benchmarking related methods +pub mod benchmark; + /// darkfid JSON-RPC related methods mod rpc; use rpc::{polling_task, DarkfidRpcClient}; diff --git a/bin/minerd/src/main.rs b/bin/minerd/src/main.rs index d80a74be9..f5da0ca06 100644 --- a/bin/minerd/src/main.rs +++ b/bin/minerd/src/main.rs @@ -32,7 +32,7 @@ use darkfi_sdk::{ pasta::pallas, }; -use minerd::{MinerNodeConfig, Minerd}; +use minerd::{benchmark::benchmark, MinerNodeConfig, Minerd}; const CONFIG_FILE: &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 threads: usize, + #[structopt(short, long)] + /// Number of nonces to execute in system hashrate benchmark + bench: Option, + #[structopt(short, long, default_value = "2")] /// Polling rate to ask darkfid for mining jobs polling_rate: u64, @@ -140,6 +144,11 @@ pub async fn parse_blockchain_config( async_daemonize!(realmain); 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..."); // Grab blockchain network configuration diff --git a/contrib/localnet/darkfid-five-nodes/minerd0.toml b/contrib/localnet/darkfid-five-nodes/minerd0.toml index 636791901..791dfaf78 100644 --- a/contrib/localnet/darkfid-five-nodes/minerd0.toml +++ b/contrib/localnet/darkfid-five-nodes/minerd0.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use threads = 1 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/contrib/localnet/darkfid-five-nodes/minerd1.toml b/contrib/localnet/darkfid-five-nodes/minerd1.toml index d4b535cb5..f699cb90f 100644 --- a/contrib/localnet/darkfid-five-nodes/minerd1.toml +++ b/contrib/localnet/darkfid-five-nodes/minerd1.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use threads = 1 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/contrib/localnet/darkfid-five-nodes/minerd2.toml b/contrib/localnet/darkfid-five-nodes/minerd2.toml index 53936dd69..068ed822a 100644 --- a/contrib/localnet/darkfid-five-nodes/minerd2.toml +++ b/contrib/localnet/darkfid-five-nodes/minerd2.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use threads = 1 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/contrib/localnet/darkfid-five-nodes/minerd3.toml b/contrib/localnet/darkfid-five-nodes/minerd3.toml index 418a3c293..be8099496 100644 --- a/contrib/localnet/darkfid-five-nodes/minerd3.toml +++ b/contrib/localnet/darkfid-five-nodes/minerd3.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use threads = 1 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/contrib/localnet/darkfid-five-nodes/minerd4.toml b/contrib/localnet/darkfid-five-nodes/minerd4.toml index aaf992abf..58d98fd00 100644 --- a/contrib/localnet/darkfid-five-nodes/minerd4.toml +++ b/contrib/localnet/darkfid-five-nodes/minerd4.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use threads = 1 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/contrib/localnet/darkfid-single-node/minerd.toml b/contrib/localnet/darkfid-single-node/minerd.toml index 349499ba4..d3de6ea00 100644 --- a/contrib/localnet/darkfid-single-node/minerd.toml +++ b/contrib/localnet/darkfid-single-node/minerd.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use #threads = 4 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/contrib/localnet/darkfid-small/minerd0.toml b/contrib/localnet/darkfid-small/minerd0.toml index 13e850bda..7735187be 100644 --- a/contrib/localnet/darkfid-small/minerd0.toml +++ b/contrib/localnet/darkfid-small/minerd0.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use threads = 2 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2 diff --git a/contrib/localnet/darkfid-small/minerd1.toml b/contrib/localnet/darkfid-small/minerd1.toml index 45e99b550..2ee200fbf 100644 --- a/contrib/localnet/darkfid-small/minerd1.toml +++ b/contrib/localnet/darkfid-small/minerd1.toml @@ -9,6 +9,9 @@ # PoW miner number of threads to use threads = 2 +# Number of nonces to execute in system hashrate benchmark +#bench = 1000 + # Polling rate to ask darkfid for mining jobs #polling_rate = 2