Просмотр исходного кода

vanityaddr: Add example on how to handle SIGINT with channels.

Another good approach as well is to consider everyting inside
rayon_pool.install() as the main() function and do things in there for
some weird simplicity. With this, one does not need to use another
channel to get a value out of the closure.
parazyd 4 лет назад
Родитель
Сommit
59687a60ee
3 измененных файлов с 35 добавлено и 12 удалено
  1. 11 0
      Cargo.lock
  2. 1 0
      bin/vanityaddr/Cargo.toml
  3. 23 12
      bin/vanityaddr/src/main.rs

+ 11 - 0
Cargo.lock

@@ -1465,6 +1465,16 @@ dependencies = [
  "cipher 0.3.0",
 ]
 
+[[package]]
+name = "ctrlc"
+version = "3.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a19c6cedffdc8c03a3346d723eb20bd85a13362bb96dc2ac000842c6381ec7bf"
+dependencies = [
+ "nix",
+ "winapi 0.3.9",
+]
+
 [[package]]
 name = "curve25519-dalek"
 version = "3.2.1"
@@ -6379,6 +6389,7 @@ version = "0.3.0"
 dependencies = [
  "bs58",
  "clap 3.1.6",
+ "ctrlc",
  "darkfi",
  "indicatif",
  "num_cpus",

+ 1 - 0
bin/vanityaddr/Cargo.toml

@@ -11,6 +11,7 @@ edition = "2021"
 [dependencies]
 bs58 = "0.4.0"
 clap = {version = "3.1.6", features = ["derive"]}
+ctrlc = "3.2.0"
 darkfi = {path = "../../", features = ["crypto", "util"]}
 indicatif = "0.16.2"
 num_cpus = "1.13.1"

+ 23 - 12
bin/vanityaddr/src/main.rs

@@ -1,4 +1,4 @@
-use std::process::exit;
+use std::{process::exit, sync::mpsc::channel};
 
 use clap::Parser;
 use indicatif::{ProgressBar, ProgressStyle};
@@ -88,28 +88,39 @@ fn main() {
     let num_threads = if args.threads.is_some() { args.threads.unwrap() } else { num_cpus::get() };
     let rayon_pool = rayon::ThreadPoolBuilder::new().num_threads(num_threads).build().unwrap();
 
+    // Handle SIGINT
+    let (tx, rx) = channel();
+    ctrlc::set_handler(move || tx.send(()).expect("Could not send signal on channel"))
+        .expect("Error setting SIGINT handler");
+
     // Something fancy
     let progress = ProgressBar::new_spinner();
     progress.set_style(ProgressStyle::default_bar().template("[{elapsed_precise}] {pos} attempts"));
     progress.set_draw_rate(10);
 
     // Fire off the threadpool
-    let addr = rayon_pool.install(|| {
-        rayon::iter::repeat(DrkAddr::new)
+    rayon_pool.spawn(move || {
+        let addr = rayon::iter::repeat(DrkAddr::new)
             .inspect(|_| progress.inc(1))
             .map(|create| create())
             .find_any(|address| address.starts_with_any(&args.prefix, args.case_sensitive))
-            .expect("Failed to find an address match")
-    });
+            .expect("Failed to find an address match");
+
+        let attempts = progress.position();
+        progress.finish_and_clear();
 
-    let attempts = progress.position();
-    progress.finish_and_clear();
+        let result = json!({
+            "address": addr.address,
+            "secret": format!("{:?}", addr.secret.0),
+            "attempts": attempts,
+        });
 
-    let result = json!({
-        "address": addr.address,
-        "secret": format!("{:?}", addr.secret.0),
-        "attempts": attempts,
+        println!("{}", result);
+        exit(0);
     });
 
-    println!("{}", result);
+    // This now blocks and lets our threadpool execute in the background.
+    rx.recv().expect("Could not receive from channel");
+    eprintln!("\rCaught SIGINT, exiting...");
+    exit(127);
 }