From 56fb05279d67288f97381b941f467c6c5077bb04 Mon Sep 17 00:00:00 2001 From: okjodom Date: Fri, 6 Oct 2023 15:51:06 -0700 Subject: [PATCH] sim-cli: source simulation file from data directory sim-cli expects SIMLN_DATA_DIR/sims to contain simulation files in json format, and it can: - prompt a user to select a file from this directory - find a pre-selected file when --sim-file option is provided --- Cargo.lock | 155 ++++++++++++++++++++++++++++++++++++++------ sim-cli/Cargo.toml | 1 + sim-cli/src/main.rs | 102 +++++++++++++++++++++++++---- 3 files changed, 226 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 8296001a..882357b5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -365,7 +365,20 @@ checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6" dependencies = [ "is-terminal", "lazy_static", - "windows-sys", + "windows-sys 0.48.0", +] + +[[package]] +name = "console" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "unicode-width", + "windows-sys 0.45.0", ] [[package]] @@ -421,7 +434,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82e95fbd621905b854affdc67943b043a0fbb6ed7385fd5a25650d19a8a6cfdf" dependencies = [ "nix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -443,6 +456,19 @@ version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f2696e8a945f658fd14dc3b87242e6b80cd0f36ff04ea560fa39082368847946" +[[package]] +name = "dialoguer" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bce805d770f407bc62102fca7c2c64ceef2fbcb2b8bd19d2765ce093980de" +dependencies = [ + "console", + "shell-words", + "tempfile", + "thiserror", + "zeroize", +] + [[package]] name = "dirs" version = "1.0.5" @@ -460,6 +486,12 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "equivalent" version = "1.0.1" @@ -474,7 +506,7 @@ checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd" dependencies = [ "errno-dragonfly", "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -724,7 +756,7 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" dependencies = [ - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -825,7 +857,7 @@ checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -936,7 +968,7 @@ checksum = "927a765cd3fc26206e66b296465fa9d3e5ab003e651c1b3c060e7956d96b19d2" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1036,7 +1068,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets", + "windows-targets 0.48.5", ] [[package]] @@ -1419,7 +1451,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1574,6 +1606,12 @@ dependencies = [ "serde", ] +[[package]] +name = "shell-words" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24188a676b6ae68c3b2cb3a01be17fbf7240ce009799bb56d5b1409051e78fde" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1591,6 +1629,7 @@ dependencies = [ "bitcoin 0.30.1", "clap", "ctrlc", + "dialoguer", "log", "serde", "serde_json", @@ -1670,7 +1709,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4031e820eb552adee9295814c0ced9e5cf38ddf1e8b7d566d6de8e2538ea989e" dependencies = [ "libc", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1733,7 +1772,7 @@ dependencies = [ "fastrand", "redox_syscall 0.3.5", "rustix", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -1802,7 +1841,7 @@ dependencies = [ "signal-hook-registry", "socket2 0.5.4", "tokio-macros", - "windows-sys", + "windows-sys 0.48.0", ] [[package]] @@ -2093,6 +2132,12 @@ version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + [[package]] name = "untrusted" version = "0.7.1" @@ -2244,13 +2289,37 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +dependencies = [ + "windows-targets 0.42.2", +] + [[package]] name = "windows-sys" version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets", + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" +dependencies = [ + "windows_aarch64_gnullvm 0.42.2", + "windows_aarch64_msvc 0.42.2", + "windows_i686_gnu 0.42.2", + "windows_i686_msvc 0.42.2", + "windows_x86_64_gnu 0.42.2", + "windows_x86_64_gnullvm 0.42.2", + "windows_x86_64_msvc 0.42.2", ] [[package]] @@ -2259,53 +2328,101 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_i686_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" + [[package]] name = "windows_i686_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" + [[package]] name = "windows_i686_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_x86_64_gnu" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_msvc" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" diff --git a/sim-cli/Cargo.toml b/sim-cli/Cargo.toml index 2e795f71..8ef2ed58 100644 --- a/sim-cli/Cargo.toml +++ b/sim-cli/Cargo.toml @@ -8,6 +8,7 @@ edition = "2021" [dependencies] anyhow = { version = "1.0.69", features = ["backtrace"] } clap = { version = "4.1.6", features = ["derive", "env", "std", "help", "usage", "error-context", "suggestions"], default-features = false } +dialoguer = "0.11.0" log = "0.4.20" serde = "1.0.183" serde_json = "1.0.104" diff --git a/sim-cli/src/main.rs b/sim-cli/src/main.rs index 66f4671d..3a03f117 100644 --- a/sim-cli/src/main.rs +++ b/sim-cli/src/main.rs @@ -1,7 +1,6 @@ use bitcoin::secp256k1::PublicKey; -use std::collections::HashMap; -use std::path::PathBuf; use std::sync::Arc; +use std::{collections::HashMap, path::PathBuf}; use tokio::sync::Mutex; use clap::Parser; @@ -15,34 +14,51 @@ use simple_logger::SimpleLogger; #[derive(Parser)] #[command(version)] struct Cli { - #[clap(index = 1)] - sim_file: PathBuf, + /// Path to folder containing simulation files and where simulation results will be written + #[arg(index = 1, env = "SIMLN_DATA_DIR")] + data_dir: PathBuf, + /// Name of the simulation file to use. These are located in `${SIMLN_DATA_DIR}/sims/` + /// and are in JSON format. If not specified, the cli will prompt the user to select one. + #[clap(long = "sim-file", short)] + sim_file: Option, + /// Total time to run the simulation for in seconds #[clap(long, short)] total_time: Option, /// Number of activity results to batch together before printing to csv file #[clap(long, short)] print_batch_size: Option, + /// Log level to use for the simulation #[clap(long, short, default_value = "info")] log_level: LevelFilter, + /// Expected payment amount seed for randomly generated simulation activities #[clap(long, short)] expected_pmt_amt: Option, + /// Capacity multiplier seed for randomly generated simulation activities #[clap(long, short)] capacity_multiplier: Option, } #[tokio::main] async fn main() -> anyhow::Result<()> { - let cli = Cli::parse(); + let Cli { + data_dir, + sim_file, + total_time, + print_batch_size, + expected_pmt_amt, + capacity_multiplier, + log_level, + } = Cli::parse(); SimpleLogger::new() .with_level(LevelFilter::Warn) - .with_module_level("sim_lib", cli.log_level) - .with_module_level("sim_cli", cli.log_level) + .with_module_level("sim_lib", log_level) + .with_module_level("sim_cli", log_level) .init() .unwrap(); - let SimParams { nodes, activity } = - serde_json::from_str(&std::fs::read_to_string(cli.sim_file)?)?; + let sim_path = read_sim_path(data_dir.clone(), sim_file).await?; + let SimParams { nodes, activity } = serde_json::from_str(&std::fs::read_to_string(sim_path)?)?; let mut clients: HashMap>> = HashMap::new(); let mut pk_node_map = HashMap::new(); @@ -145,10 +161,10 @@ async fn main() -> anyhow::Result<()> { let sim = Simulation::new( clients, validated_activities, - cli.total_time, - cli.print_batch_size, - cli.expected_pmt_amt, - cli.capacity_multiplier, + total_time, + print_batch_size, + expected_pmt_amt, + capacity_multiplier, ); let sim2 = sim.clone(); @@ -161,3 +177,63 @@ async fn main() -> anyhow::Result<()> { Ok(()) } + +async fn mkdir(dir: PathBuf) -> anyhow::Result { + if !dir.exists() { + tokio::fs::create_dir(&dir).await?; + } + Ok(dir) +} + +async fn read_sim_path(data_dir: PathBuf, sim_file: Option) -> anyhow::Result { + let sims_path = mkdir(data_dir.join("sims")).await?; + + match sim_file { + Some(sim_file) => { + let sim_path = sims_path.join(sim_file); + + let sim_path = if sim_path.extension().is_none() { + sim_path.with_extension("json") + } else { + sim_path + }; + + if sim_path.exists() { + Ok(sim_path) + } else { + anyhow::bail!(format!( + "simulation file {} not found.", + sim_path.to_str().unwrap() + )); + } + } + None => { + let sim_files: Vec = std::fs::read_dir(sims_path.clone())? + .filter_map(|f| { + f.ok().and_then(|f| { + if f.path().extension().unwrap_or_default() == "json" { + Some(f.file_name().into_string().unwrap()) + } else { + None + } + }) + }) + .collect::>(); + + if sim_files.is_empty() { + anyhow::bail!( + "no simulation files found in {}.", + sims_path.to_str().unwrap() + ); + } + + let selection = dialoguer::Select::new() + .with_prompt("Select a simulation file") + .items(&sim_files) + .default(0) + .interact()?; + + Ok(sims_path.join(sim_files[selection].clone())) + } + } +}