Procházet zdrojové kódy

minerd: rest randomx flags added for configuring miner

skoupidi před 8 měsíci
rodič
revize
fc78a6f91d

+ 12 - 3
bin/minerd/minerd.toml

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-#threads = 4
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+#threads = 4
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

+ 10 - 3
bin/minerd/src/benchmark.rs

@@ -31,13 +31,19 @@ use tracing::{error, info};
 use darkfi::{
     blockchain::{Header, HeaderHash},
     util::time::Timestamp,
-    validator::pow::generate_mining_vms,
+    validator::pow::{generate_mining_vms, get_mining_flags},
     Result,
 };
 
 /// Performs provided number of nonces simulating mining for provided
 /// threads count to determine system hashrate.
-pub fn benchmark(threads: usize, nonces: u64) -> Result<()> {
+pub fn benchmark(
+    fast_mode: bool,
+    large_pages: bool,
+    secure: bool,
+    threads: usize,
+    nonces: u64,
+) -> Result<()> {
     // Check provided params are valid
     if threads == 0 {
         error!(target: "minerd::benchmark", "No threads were configured!");
@@ -55,7 +61,8 @@ pub fn benchmark(threads: usize, nonces: u64) -> Result<()> {
         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)?;
+    let flags = get_mining_flags(fast_mode, large_pages, secure);
+    let vms = generate_mining_vms(flags, &key, threads, &recvr)?;
 
     // Use a dummy header to mine for reproducible results
     let header = Header::new(key, 1, Timestamp::from_u64(1765378623), 0);

+ 21 - 1
bin/minerd/src/lib.rs

@@ -41,6 +41,12 @@ use rpc::{polling_task, DarkfidRpcClient};
 
 /// Auxiliary structure representing miner node configuration.
 pub struct MinerNodeConfig {
+    /// Flag indicating whether to mine in fast mode
+    fast_mode: bool,
+    /// Flag indicating whether to mine with Large Pages
+    large_pages: bool,
+    /// Flag indicating whether to mine with secure access to JIT memory (if supported)
+    secure: bool,
     /// PoW miner number of threads to use
     threads: usize,
     /// Polling rate to ask darkfid for mining jobs
@@ -54,6 +60,9 @@ pub struct MinerNodeConfig {
 impl Default for MinerNodeConfig {
     fn default() -> Self {
         Self::new(
+            true,
+            false,
+            false,
             1,
             5,
             0,
@@ -67,12 +76,23 @@ impl Default for MinerNodeConfig {
 
 impl MinerNodeConfig {
     pub fn new(
+        fast_mode: bool,
+        large_pages: bool,
+        secure: bool,
         threads: usize,
         polling_rate: u64,
         stop_at_height: u32,
         wallet_config: HashMap<String, JsonValue>,
     ) -> Self {
-        Self { threads, polling_rate, stop_at_height, wallet_config }
+        Self {
+            fast_mode,
+            large_pages,
+            secure,
+            threads,
+            polling_rate,
+            stop_at_height,
+            wallet_config,
+        }
     }
 }
 

+ 26 - 7
bin/minerd/src/main.rs

@@ -45,14 +45,26 @@ struct Args {
     /// Configuration file to use
     config: Option<String>,
 
-    #[structopt(short, long, default_value = "4")]
-    /// PoW miner number of threads to use
-    threads: usize,
-
     #[structopt(short, long)]
     /// Number of nonces to execute in system hashrate benchmark
     bench: Option<u64>,
 
+    #[structopt(long)]
+    /// Flag indicating whether to run miner in light mode
+    light_mode: bool,
+
+    #[structopt(long)]
+    /// Flag indicating whether to run miner with Large Pages
+    large_pages: bool,
+
+    #[structopt(long)]
+    /// Flag indicating whether to run miner with secure access to JIT memory (if supported)
+    secure: bool,
+
+    #[structopt(short, long, default_value = "4")]
+    /// PoW miner number of threads to use
+    threads: usize,
+
     #[structopt(short, long, default_value = "2")]
     /// Polling rate to ask darkfid for mining jobs
     polling_rate: u64,
@@ -146,7 +158,7 @@ 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)
+        return benchmark(!args.light_mode, args.large_pages, args.secure, args.threads, nonces)
     }
 
     info!(target: "minerd", "Starting DarkFi Mining Daemon...");
@@ -193,8 +205,15 @@ async fn realmain(args: Args, ex: ExecutorPtr) -> Result<()> {
     }
 
     // Generate the daemon
-    let miner_config =
-        MinerNodeConfig::new(args.threads, args.polling_rate, args.stop_at_height, wallet_config);
+    let miner_config = MinerNodeConfig::new(
+        !args.light_mode,
+        args.large_pages,
+        args.secure,
+        args.threads,
+        args.polling_rate,
+        args.stop_at_height,
+        wallet_config,
+    );
     let daemon = Minerd::init(miner_config, blockchain_config.endpoint, &ex).await;
     daemon.start(&ex);
 

+ 11 - 5
bin/minerd/src/rpc.rs

@@ -19,7 +19,7 @@
 use std::{sync::Arc, thread};
 
 use num_bigint::BigUint;
-use randomx::RandomXVM;
+use randomx::{RandomXFlags, RandomXVM};
 use smol::channel::{Receiver, Sender};
 use tracing::{debug, error, info};
 use url::Url;
@@ -29,7 +29,7 @@ use darkfi::{
     rpc::{client::RpcClient, jsonrpc::JsonRequest, util::JsonValue},
     system::{sleep, ExecutorPtr, StoppableTask},
     util::encoding::base64,
-    validator::pow::{generate_mining_vms, mine_block},
+    validator::pow::{generate_mining_vms, get_mining_flags, mine_block},
     Error, Result,
 };
 use darkfi_serial::deserialize_async;
@@ -276,7 +276,10 @@ pub async fn polling_task(miner: MinerNodePtr, ex: ExecutorPtr) -> Result<()> {
     // Cache current and next RandomX keys and current VMs
     let (mut current_randomx_key, mut next_randomx_key) = miner.randomx_keys().await?;
     info!(target: "minerd::rpc::mining_task", "Initializing {} mining VMs for key: {current_randomx_key}", miner.config.threads);
+    let mining_flags =
+        get_mining_flags(miner.config.fast_mode, miner.config.large_pages, miner.config.secure);
     let mut current_vms = Arc::new(generate_mining_vms(
+        mining_flags,
         &current_randomx_key,
         miner.config.threads,
         &miner.mining_channel.1.clone(),
@@ -291,7 +294,8 @@ pub async fn polling_task(miner: MinerNodePtr, ex: ExecutorPtr) -> Result<()> {
         let sender = vms_sender.clone();
         let stop_singal = miner.background_channel.1.clone();
         thread::spawn(move || {
-            match vms_generation_task(next_randomx_key, threads, sender, stop_singal) {
+            match vms_generation_task(mining_flags, next_randomx_key, threads, sender, stop_singal)
+            {
                 Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
                 Err(e) => {
                     error!(target: "minerd::rpc::polling_task", "RandomX VMs generation task failed: {e}")
@@ -344,6 +348,7 @@ pub async fn polling_task(miner: MinerNodePtr, ex: ExecutorPtr) -> Result<()> {
                 // Generate the RandomX VMs for the key
                 info!(target: "minerd::rpc::mining_task", "Initializing {} mining VMs for key: {randomx_key}", miner.config.threads);
                 current_vms = Arc::new(generate_mining_vms(
+                    mining_flags,
                     &randomx_key,
                     miner.config.threads,
                     &miner.mining_channel.1.clone(),
@@ -366,7 +371,7 @@ pub async fn polling_task(miner: MinerNodePtr, ex: ExecutorPtr) -> Result<()> {
             let sender = vms_sender.clone();
             let stop_singal = miner.background_channel.1.clone();
             thread::spawn(move || {
-                match vms_generation_task(next_key, threads, sender, stop_singal) {
+                match vms_generation_task(mining_flags, next_key, threads, sender, stop_singal) {
                     Ok(()) | Err(Error::DetachedTaskStopped) => { /* Do nothing */ }
                     Err(e) => {
                         error!(target: "minerd::rpc::polling_task", "RandomX VMs generation task failed: {e}")
@@ -427,6 +432,7 @@ async fn mining_task(
 /// Async task to generate RandomX VMs in the background and push them
 /// in provided channel.
 fn vms_generation_task(
+    mining_flags: RandomXFlags,
     randomx_key: HeaderHash,
     threads: usize,
     sender: Sender<Vec<Arc<RandomXVM>>>,
@@ -434,7 +440,7 @@ fn vms_generation_task(
 ) -> Result<()> {
     // Generate the RandomX VMs for the key
     info!(target: "minerd::rpc::vms_generation_task", "Initializing {threads} mining VMs for key: {randomx_key}");
-    let vms = generate_mining_vms(&randomx_key, threads, &stop_signal)?;
+    let vms = generate_mining_vms(mining_flags, &randomx_key, threads, &stop_signal)?;
     // Push them into the channel
     sender.send_blocking(vms)?;
     Ok(())

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-threads = 1
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+threads = 1
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-threads = 1
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+threads = 1
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-threads = 1
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+threads = 1
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-threads = 1
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+threads = 1
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-threads = 1
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+threads = 1
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-#threads = 4
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+#threads = 4
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-threads = 2
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+threads = 2
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

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

@@ -6,12 +6,21 @@
 ## The default values are left commented. They can be overridden either by
 ## uncommenting, or by using the command-line.
 
-# PoW miner number of threads to use
-threads = 2
-
 # Number of nonces to execute in system hashrate benchmark
 #bench = 1000
 
+# Flag indicating whether to run miner in light mode
+light_mode = false
+
+# Flag indicating whether to run miner with Large Pages
+large_pages = false
+
+# Flag indicating whether to run miner with secure access to JIT memory (if supported)
+secure = false
+
+# PoW miner number of threads to use
+threads = 2
+
 # Polling rate to ask darkfid for mining jobs
 #polling_rate = 2
 

+ 29 - 11
src/validator/pow.rs

@@ -389,6 +389,7 @@ impl PoWModule {
     }
 
     /// Mine provided block, based on next mine target.
+    /// Note: this is used in tests not in actual mining.
     pub fn mine_block(
         &self,
         header: &mut Header,
@@ -407,7 +408,8 @@ impl PoWModule {
         };
 
         // Generate the RandomX VMs for the key
-        let vms = generate_mining_vms(randomx_key, threads, stop_signal)?;
+        let flags = get_mining_flags(false, false, false);
+        let vms = generate_mining_vms(flags, randomx_key, threads, stop_signal)?;
 
         // Grab the next mine target
         let target = self.next_mine_target()?;
@@ -431,9 +433,18 @@ impl std::fmt::Display for PoWModule {
 ///
 /// Note: RandomX recommended flags will include `SSSE3` and `AVX2`
 /// extensions if CPU supports them.
-fn get_mining_flags() -> RandomXFlags {
-    // TODO: Try adding `| RandomXFlags::LARGEPAGES`.
-    RandomXFlags::get_recommended_flags() | RandomXFlags::FULLMEM
+pub fn get_mining_flags(fast_mode: bool, large_pages: bool, secure: bool) -> RandomXFlags {
+    let mut flags = RandomXFlags::get_recommended_flags();
+    if fast_mode {
+        flags |= RandomXFlags::FULLMEM;
+    }
+    if large_pages {
+        flags |= RandomXFlags::LARGEPAGES;
+    }
+    if secure && flags.contains(RandomXFlags::JIT) {
+        flags |= RandomXFlags::SECURE;
+    }
+    flags
 }
 
 /// Auxiliary function to initialize a `RandomXDataset` using all
@@ -485,24 +496,31 @@ fn init_dataset(
 
 /// Auxiliary function to generate mining VMs for provided RandomX key.
 pub fn generate_mining_vms(
+    flags: RandomXFlags,
     input: &HeaderHash,
     threads: usize,
     stop_signal: &Receiver<()>,
 ) -> Result<Vec<Arc<RandomXVM>>> {
-    // Initialize dataset
     debug!(target: "validator::pow::generate_mining_vms", "[MINER] Initializing RandomX cache and dataset...");
     debug!(target: "validator::pow::generate_mining_vms", "[MINER] PoW input: {input}");
     let setup_start = Instant::now();
-    let ds_start = Instant::now();
-    let flags = get_mining_flags();
-    let dataset = init_dataset(flags, input, stop_signal)?;
-    debug!(target: "validator::pow::generate_mining_vms", "[MINER] Initialized RandomX cache and dataset: {:?}", ds_start.elapsed());
+    // Check if fast mode is enabled
+    let (cache, dataset) = if flags.contains(RandomXFlags::FULLMEM) {
+        // Initialize dataset
+        let dataset = init_dataset(flags, input, stop_signal)?;
+        (None, Some(dataset))
+    } else {
+        // Initialize cache for light mode
+        let cache = RandomXCache::new(flags, &input.inner()[..])?;
+        (Some(cache), None)
+    };
+    debug!(target: "validator::pow::generate_mining_vms", "[MINER] Initialized RandomX cache and dataset: {:?}", setup_start.elapsed());
 
     // Single thread mining VM
     if threads == 1 {
         debug!(target: "validator::pow::generate_mining_vms", "[MINER] Initializing RandomX VM...");
         let vm_start = Instant::now();
-        let vm = Arc::new(RandomXVM::new(flags, None, Some(dataset))?);
+        let vm = Arc::new(RandomXVM::new(flags, cache, dataset)?);
         debug!(target: "validator::pow::generate_mining_vms", "[MINER] Initialized RandomX VM in {:?}", vm_start.elapsed());
         debug!(target: "validator::pow::generate_mining_vms", "[MINER] Setup time: {:?}", setup_start.elapsed());
         return Ok(vec![vm])
@@ -521,7 +539,7 @@ pub fn generate_mining_vms(
 
         debug!(target: "validator::pow::generate_mining_vms", "[MINER] Initializing RandomX VM #{t}...");
         let vm_start = Instant::now();
-        vms.push(Arc::new(RandomXVM::new(flags, None, Some(dataset.clone()))?));
+        vms.push(Arc::new(RandomXVM::new(flags, cache.clone(), dataset.clone())?));
         debug!(target: "validator::pow::generate_mining_vms", "[MINER] Initialized RandomX VM #{t} in {:?}", vm_start.elapsed());
     }
     debug!(target: "validator::pow::generate_mining_vms", "[MINER] Setup time: {:?}", setup_start.elapsed());