hashiverse_client_wasm/
lib.rs1#![feature(try_blocks)]
2pub mod wasm_transport;
3pub mod wasm_bootstrap_provider;
4pub mod wasm_local_settings;
5pub mod wasm_client_storage;
6pub mod wasm_key_locker;
7pub mod wasm_parallel_pow_generator;
8pub mod with_js_context;
9pub mod hashiverse_client_wasm;
10pub mod wasm_try;
11
12use hashiverse_lib::tools::pow::pow_measure_from_data_hash;
13use hashiverse_lib::tools::types::{Hash, Pow, Salt};
14use log::{info, trace};
15use std::sync::Arc;
16use wasm_bindgen::prelude::*;
17
18#[wasm_bindgen]
21pub fn wasm_init(verbose: bool) {
22
23 {
25 fern::Dispatch::new()
26 .level(log::LevelFilter::Trace) .level_for("wasm_bindgen", log::LevelFilter::Warn)
28 .level_for("scraper", log::LevelFilter::Warn)
29 .level_for("html5ever", log::LevelFilter::Warn)
30 .level_for("selectors", log::LevelFilter::Warn)
31 .chain(fern::Output::call(console_log::log))
32 .apply()
33 .expect("Failed to initialize logging")
34 ;
35
36 if verbose {
37 info!("Logging initialized");
38 }
39 }
40
41 console_error_panic_hook::set_once();
42 if verbose {
43 trace!("WASM module panic hook set");
44 }
45}
46
47#[wasm_bindgen]
52pub fn pow_compute_batch(iteration_limit: u32, pow_min: u8, data_hash_hex: String) -> String {
53 let data_hash = match hex::decode(&data_hash_hex).ok().and_then(|b| Hash::from_slice(&b).ok()) {
54 Some(h) => h,
55 None => return format!("{}:0:{}", hex::encode(Salt::zero()), hex::encode(Hash::zero())),
56 };
57
58 let pow_min = Pow(pow_min);
59 let mut best = (Salt::zero(), Pow(0), Hash::zero());
60
61 for _ in 0..iteration_limit {
62 let salt = Salt::random();
63 if let Ok((pow, hash)) = pow_measure_from_data_hash(&data_hash, &salt) {
64 if pow > best.1 {
65 best = (salt, pow, hash);
66 if pow >= pow_min {
67 break;
68 }
69 }
70 }
71 }
72 format!("{}:{}:{}", hex::encode(best.0), best.1 .0, hex::encode(best.2))
73}
74
75static WASM_PARALLEL_POW_GENERATOR: std::sync::OnceLock<Arc<wasm_parallel_pow_generator::WasmParallelPowGenerator>> = std::sync::OnceLock::new();
77
78#[wasm_bindgen]
81pub fn init_pow_workers(workers_js: JsValue) {
82 let workers_array: js_sys::Array = match workers_js.dyn_into() {
83 Ok(a) => a,
84 Err(_) => {
85 log::warn!("init_pow_workers: expected an Array of Workers");
86 return;
87 }
88 };
89
90 let mut workers = Vec::new();
91 for i in 0..workers_array.length() {
92 let val = workers_array.get(i);
93 match val.dyn_into::<web_sys::Worker>() {
94 Ok(w) => workers.push(w),
95 Err(_) => log::warn!("init_pow_workers: element {} is not a Worker", i),
96 }
97 }
98
99 if workers.is_empty() {
100 log::warn!("init_pow_workers: no valid Workers provided");
101 return;
102 }
103
104 let generator = wasm_parallel_pow_generator::WasmParallelPowGenerator::from_workers(workers);
105 let _ = WASM_PARALLEL_POW_GENERATOR.set(Arc::new(generator));
106}
107
108pub fn get_wasm_parallel_pow_generator() -> Option<Arc<wasm_parallel_pow_generator::WasmParallelPowGenerator>> {
110 WASM_PARALLEL_POW_GENERATOR.get().cloned()
111}