feat: abs all options

This commit is contained in:
Aravinth Manivannan 2023-08-04 11:42:44 +05:30
parent 756ddf8093
commit 262bb6bfbf
Signed by: realaravinth
GPG key ID: AD9F0F08E855ED88
8 changed files with 291 additions and 210 deletions

59
src/avg.rs Normal file
View file

@ -0,0 +1,59 @@
use std::time::Instant;
use rayon::prelude::*;
use pow_sha256::ConfigBuilder;
use crate::utils::get_random;
#[derive(clap::Args, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct AvgGenerate {
#[arg(long)]
pub start: u32,
#[arg(long)]
pub max: u32,
#[arg(long)]
pub trials: u32,
#[arg(long)]
pub db: url::Url,
}
impl AvgGenerate {
pub fn run(&self) {
(self.start..self.max)
.into_par_iter()
.for_each(|difficulty| {
let mut summary = String::new();
let mut times: Vec<u128> = Vec::with_capacity(self.trials as usize);
for _ in 0..self.trials {
let salt = get_random(32);
let string = get_random(32);
let pow_config = ConfigBuilder::default().salt(salt.clone()).build().unwrap();
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();
log::info!("Difficulty factor {difficulty} generated in {time}");
times.push(time);
}
let mean = (times.iter().sum::<u128>() / self.trials as u128) as u32;
let simple_variance: u32 = (times
.iter()
.map(|d| {
let x = (*d as u32 - mean) as u32;
x * x
})
.sum::<u32>())
/ (self.trials as u32 - 1);
let simple_variance: usize = (simple_variance as f32).sqrt() as usize;
let min = times.iter().min().unwrap();
let max = times.iter().max().unwrap();
summary = format!("{summary}\ndifficulty: {difficulty} min: {min} max: {max} mean: {mean} variance {simple_variance}");
println!("{summary}");
});
}
}

45
src/cli.rs Normal file
View file

@ -0,0 +1,45 @@
use clap::Parser;
use crate::avg::AvgGenerate;
use crate::diff::ForDiff;
use crate::gen::GenerateDeriveArgs;
use crate::migrate_pg::SledToPostgres;
use crate::print::PrintRes;
#[derive(Parser)] // requires `derive` feature
#[command(name = "cargo")]
#[command(bin_name = "cargo")]
pub enum PoWdCli {
Generate(GenerateDeriveArgs),
PrintDB(PrintRes),
SledToPostgres(SledToPostgres),
ForDiff(ForDiff),
AvgGenerate(AvgGenerate),
}
impl PoWdCli {
pub async fn run() {
match PoWdCli::parse() {
PoWdCli::Generate(args) => {
println!("{:?}", args);
args.run();
}
PoWdCli::PrintDB(args) => {
println!("{:?}", args);
args.run()
}
PoWdCli::SledToPostgres(args) => {
args.run().await;
}
PoWdCli::ForDiff(args) => {
println!("{:?}", args);
args.run();
}
PoWdCli::AvgGenerate(args) => {
args.run().await;
}
}
}
}

58
src/diff.rs Normal file
View file

@ -0,0 +1,58 @@
use std::time::Instant;
use pow_sha256::ConfigBuilder;
use crate::utils::get_random;
#[derive(clap::Args, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct ForDiff {
#[arg(long)]
pub factors: String,
}
impl ForDiff {
pub fn run(&self) {
let factors: Vec<u32> = self
.factors
.split(',')
.map(|d| d.parse::<u32>().unwrap())
.collect();
let mut summary = String::new();
for difficulty in factors.iter() {
let trials = 100;
let mut times: Vec<u128> = Vec::with_capacity(trials);
for _ in 0..trials {
let salt = get_random(32);
let string = get_random(32);
let pow_config = ConfigBuilder::default().salt(salt.clone()).build().unwrap();
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();
log::info!("Difficulty factor {difficulty} generated in {time}");
times.push(time);
}
let mean = (times.iter().sum::<u128>() / trials as u128) as u32;
let simple_variance: u32 = (times
.iter()
.map(|d| {
let x = (*d as u32 - mean) as u32;
x * x
})
.sum::<u32>())
/ (trials as u32 - 1);
let simple_variance: usize = (simple_variance as f32).sqrt() as usize;
let min = times.iter().min().unwrap();
let max = times.iter().max().unwrap();
summary = format!("{summary}\ndifficulty: {difficulty} min: {min} max: {max} mean: {mean} variance {simple_variance}");
}
println!("{summary}");
}
}

61
src/gen.rs Normal file
View file

@ -0,0 +1,61 @@
use std::time::Instant;
use pow_sha256::ConfigBuilder;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use crate::utils::get_random;
#[derive(clap::Args, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct GenerateDeriveArgs {
#[arg(long)]
pub start: u32,
#[arg(long)]
pub max: u32,
#[arg(long)]
pub db: std::path::PathBuf,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Log {
pub string: String,
pub salt: String,
pub time: u128,
}
impl GenerateDeriveArgs {
pub 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();
});
}
}

View file

@ -2,221 +2,21 @@
//
// SPDX-License-Identifier: AGPL-3.0-or-later
use clap::Parser;
use pow_sha256::ConfigBuilder;
use rayon::prelude::*;
use serde::{Deserialize, Serialize};
use sqlx::postgres::PgPoolOptions;
use std::time::Duration;
use std::time::Instant;
mod avg;
mod cli;
mod db;
mod diff;
mod print;
mod gen;
mod migrate_pg;
mod utils;
#[derive(Parser)] // requires `derive` feature
#[command(name = "cargo")]
#[command(bin_name = "cargo")]
enum PoWdCli {
Generate(GenerateDeriveArgs),
PrintDB(PrintRes),
Sqlite(Sqlite),
ForDiff(ForDiff),
}
pub(crate) use gen::Log;
#[derive(clap::Args, Debug, Clone)]
#[command(author, version, about, long_about = None)]
struct ForDiff {
#[arg(long)]
factors: String,
}
impl ForDiff {
fn run(&self) {
let factors: Vec<u32> = self
.factors
.split(',')
.map(|d| d.parse::<u32>().unwrap())
.collect();
let mut summary = String::new();
for difficulty in factors.iter() {
let trials = 100;
let mut times: Vec<u128> = Vec::with_capacity(trials);
for _ in 0..trials {
let salt = get_random(32);
let string = get_random(32);
let pow_config = ConfigBuilder::default().salt(salt.clone()).build().unwrap();
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();
log::info!("Difficulty factor {difficulty} generated in {time}");
times.push(time);
}
let mean = (times.iter().sum::<u128>() / trials as u128) as u32;
let simple_variance: u32 = (times
.iter()
.map(|d| {
let x = (*d as u32 - mean) as u32;
x * x
})
.sum::<u32>())
/ (trials as u32 - 1);
let simple_variance: usize = ((simple_variance as f32).sqrt() as usize);
let min = times.iter().min().unwrap();
let max = times.iter().max().unwrap();
summary = format!("{summary}\ndifficulty: {difficulty} min: {min} max: {max} mean: {mean} variance {simple_variance}");
}
println!("{summary}");
}
}
#[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,
}
#[derive(clap::Args, Debug, Clone)]
#[command(author, version, about, long_about = None)]
struct Plot {
#[arg(long)]
graph: 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 = PgPoolOptions::new()
.max_connections(1)
.acquire_timeout(Duration::new(1000, 0))
.idle_timeout(Duration::new(1000, 0))
.connect(&args.sqlite.to_string())
.await
.unwrap();
sqlx::migrate!("./migrations/")
.run(&sqlite_db)
.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 as i32;
sqlx::query!(
"INSERT INTO logs (string, salt, time, difficulty) VALUES ($1, $2, $3, $4) ON CONFLICT(difficulty) DO NOTHING;",
log.string,
log.salt,
time,
difficulty as i32,
).execute(&sqlite_db).await.unwrap();
}
}
PoWdCli::ForDiff(args) => {
println!("{:?}", args);
args.run();
}
}
}
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>()
cli::PoWdCli::run().await;
}

25
src/migrate_pg.rs Normal file
View file

@ -0,0 +1,25 @@
use crate::db;
use crate::Log;
#[derive(clap::Args, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct SledToPostgres {
#[arg(long)]
pub sled: std::path::PathBuf,
#[arg(long)]
pub pg: url::Url,
}
impl SledToPostgres {
pub async fn run(&self) {
let pool = db::DB::new(&self.pg, 1).await;
let sled_db = sled::open(&self.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();
pool.write_log(&log, difficulty).await;
}
}
}

20
src/print.rs Normal file
View file

@ -0,0 +1,20 @@
use crate::Log;
#[derive(clap::Args, Debug, Clone)]
#[command(author, version, about, long_about = None)]
pub struct PrintRes {
#[arg(long)]
pub db: std::path::PathBuf,
}
impl PrintRes {
pub fn run(&self) {
let db = sled::open(&self.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);
}
}
}

13
src/utils.rs Normal file
View file

@ -0,0 +1,13 @@
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>()
}