146 lines
4.2 KiB
Rust
146 lines
4.2 KiB
Rust
// SPDX-FileCopyrightText: 2023 Aravinth Manivannan <realaravinth@batsense.net>
|
|
//
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
use clap::Parser;
|
|
use pow_sha256::ConfigBuilder;
|
|
use rayon::prelude::*;
|
|
use serde::{Deserialize, Serialize};
|
|
use sqlx::sqlite::SqlitePoolOptions;
|
|
use std::time::Instant;
|
|
|
|
#[derive(Parser)] // requires `derive` feature
|
|
#[command(name = "cargo")]
|
|
#[command(bin_name = "cargo")]
|
|
enum PoWdCli {
|
|
Generate(GenerateDeriveArgs),
|
|
PrintDB(PrintRes),
|
|
Sqlite(Sqlite),
|
|
}
|
|
|
|
#[derive(clap::Args, Debug, Clone)]
|
|
#[command(author, version, about, long_about = None)]
|
|
struct GenerateDeriveArgs {
|
|
#[arg(long)]
|
|
start: u32,
|
|
#[arg(long)]
|
|
max: u32,
|
|
#[arg(long)]
|
|
db: std::path::PathBuf,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
struct Log {
|
|
string: String,
|
|
salt: String,
|
|
time: u128,
|
|
}
|
|
|
|
impl GenerateDeriveArgs {
|
|
fn run(&self) {
|
|
let db = sled::open(&self.db).unwrap();
|
|
let salt = get_random(32);
|
|
let string = get_random(32);
|
|
let pow_config = ConfigBuilder::default().salt(salt.clone()).build().unwrap();
|
|
|
|
(self.start..self.max)
|
|
.into_par_iter()
|
|
.for_each(|difficulty| {
|
|
let start = Instant::now();
|
|
pow_config.prove_work(&string, difficulty).unwrap();
|
|
let finish = Instant::now();
|
|
let time_elapsed = finish.duration_since(start);
|
|
|
|
let time = time_elapsed.as_micros();
|
|
if difficulty % 10000 == 0 {
|
|
log::info!("Difficulty factor {difficulty} generated in {time}");
|
|
}
|
|
|
|
let log = Log {
|
|
salt: salt.clone(),
|
|
time,
|
|
string: string.clone(),
|
|
};
|
|
|
|
db.insert(
|
|
bincode::serialize(&difficulty).unwrap(),
|
|
bincode::serialize(&log).unwrap(),
|
|
)
|
|
.unwrap();
|
|
});
|
|
}
|
|
}
|
|
|
|
#[derive(clap::Args, Debug, Clone)]
|
|
#[command(author, version, about, long_about = None)]
|
|
struct PrintRes {
|
|
#[arg(long)]
|
|
db: std::path::PathBuf,
|
|
}
|
|
|
|
#[derive(clap::Args, Debug, Clone)]
|
|
#[command(author, version, about, long_about = None)]
|
|
struct Sqlite {
|
|
#[arg(long)]
|
|
sled: std::path::PathBuf,
|
|
#[arg(long)]
|
|
sqlite: url::Url,
|
|
}
|
|
|
|
#[actix_rt::main]
|
|
async fn main() {
|
|
std::env::set_var("RUST_LOG", "INFO");
|
|
pretty_env_logger::init();
|
|
match PoWdCli::parse() {
|
|
PoWdCli::Generate(args) => {
|
|
println!("{:?}", args);
|
|
args.run();
|
|
}
|
|
PoWdCli::PrintDB(args) => {
|
|
println!("{:?}", args);
|
|
let db = sled::open(args.db).unwrap();
|
|
for entry in db.iter() {
|
|
let (difficulty, entry) = entry.unwrap();
|
|
let log: Log = bincode::deserialize::<Log>(&entry[..]).unwrap();
|
|
let difficulty: u32 = bincode::deserialize::<u32>(&difficulty).unwrap();
|
|
println!("{difficulty}: {}", log.time);
|
|
}
|
|
}
|
|
|
|
PoWdCli::Sqlite(args) => {
|
|
let sqlite_db = SqlitePoolOptions::new().connect(&args.sqlite.to_string()).await.unwrap();
|
|
|
|
println!("{:?}", args);
|
|
let sled_db = sled::open(args.sled).unwrap();
|
|
for entry in sled_db.iter() {
|
|
let (difficulty, entry) = entry.unwrap();
|
|
let log: Log = bincode::deserialize::<Log>(&entry[..]).unwrap();
|
|
let difficulty: u32 = bincode::deserialize::<u32>(&difficulty).unwrap();
|
|
|
|
let time = log.time.to_string();
|
|
sqlx::query!(
|
|
"INSERT OR IGNORE INTO logs (string, salt, time, difficulty) VALUES ($1, $2, $3, $4);",
|
|
log.string,
|
|
log.salt,
|
|
time,
|
|
difficulty
|
|
).execute(&sqlite_db).await.unwrap();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn get_random(len: usize) -> String {
|
|
use std::iter;
|
|
|
|
use rand::{distributions::Alphanumeric, rngs::ThreadRng, thread_rng, Rng};
|
|
|
|
let mut rng: ThreadRng = thread_rng();
|
|
|
|
iter::repeat(())
|
|
.map(|()| rng.sample(Alphanumeric))
|
|
.map(char::from)
|
|
.take(len)
|
|
.collect::<String>()
|
|
}
|