Skip to content

Commit 65825c2

Browse files
committed
Save sim results as json
1 parent c23b0ac commit 65825c2

File tree

4 files changed

+102
-2
lines changed

4 files changed

+102
-2
lines changed

Cargo.lock

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ env_logger = "0.11.8"
3232
rand_distr = "0.5.1"
3333
rand_pcg = "0.9.0"
3434
serde = { version = "1.0", features = ["derive"] }
35+
serde_json = "1.0"
3536
toml = "0.8"

src/lib.rs

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use rand_distr::Distribution;
1010
use rand_distr::Geometric;
1111
use rand_pcg::rand_core::{RngCore, SeedableRng};
1212
use rand_pcg::Pcg64;
13+
use serde::Serialize;
1314

1415
use crate::bulletin_board::BroadcastMessageType;
1516
use crate::bulletin_board::BulletinBoardData;
@@ -726,6 +727,26 @@ pub struct WalletUtxoStats {
726727
pub p90: Option<Amount>,
727728
}
728729

730+
#[derive(Serialize)]
731+
struct SimulationResultJson {
732+
total_payment_obligations: usize,
733+
percentage_payment_obligations_missed: f64,
734+
total_block_weight_wu: u64,
735+
average_fee_cost_sats: u64,
736+
dust_utxo_count: usize,
737+
utxo_size_distribution_sats: Vec<u64>,
738+
wallet_utxo_stats: Vec<WalletUtxoStatsJson>,
739+
}
740+
741+
#[derive(Serialize)]
742+
struct WalletUtxoStatsJson {
743+
wallet_id: usize,
744+
dust_count: usize,
745+
total_count: usize,
746+
p50_sats: Option<u64>,
747+
p90_sats: Option<u64>,
748+
}
749+
729750
impl SimulationResult {
730751
pub fn new(sim: &Simulation) -> Self {
731752
Self {
@@ -873,7 +894,38 @@ impl SimulationResult {
873894
.unwrap();
874895
std::fs::write(path, graph_svg).unwrap();
875896
}
876-
// TODO: utxo fragmentation, anon set metrics
897+
898+
/// Save simulation results as a JSON file.
899+
pub fn save_results_json(&self, path: impl AsRef<Path>) {
900+
let utxo_sizes = self
901+
.utxo_size_distribution()
902+
.into_iter()
903+
.map(|amount| amount.to_sat())
904+
.collect();
905+
let wallet_utxo_stats = self
906+
.wallet_utxo_stats()
907+
.into_iter()
908+
.map(|stats| WalletUtxoStatsJson {
909+
wallet_id: stats.wallet_id,
910+
dust_count: stats.dust_count,
911+
total_count: stats.total_count,
912+
p50_sats: stats.p50.map(|amount| amount.to_sat()),
913+
p90_sats: stats.p90.map(|amount| amount.to_sat()),
914+
})
915+
.collect();
916+
let result = SimulationResultJson {
917+
total_payment_obligations: self.total_payment_obligations(),
918+
percentage_payment_obligations_missed: self.percentage_of_payment_obligations_missed(),
919+
total_block_weight_wu: self.total_block_weight(),
920+
average_fee_cost_sats: self.average_fee_cost().to_sat(),
921+
dust_utxo_count: self.dust_utxo_count(),
922+
utxo_size_distribution_sats: utxo_sizes,
923+
wallet_utxo_stats,
924+
};
925+
let file = std::fs::File::create(path).unwrap();
926+
serde_json::to_writer_pretty(file, &result).unwrap();
927+
}
928+
// TODO: anon set metrics
877929
}
878930

879931
fn percentile_amount(sorted: &[Amount], percentile: f64) -> Option<Amount> {

src/main.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
use std::env;
2+
use std::path::PathBuf;
3+
4+
use clap::Parser;
5+
6+
#[derive(Parser)]
7+
struct Args {
8+
/// Directory to save graph, results JSON, and config.
9+
#[arg(long, value_name = "DIR")]
10+
artifacts_dir: Option<PathBuf>,
11+
}
212

313
fn main() {
414
env_logger::init();
15+
let args = Args::parse();
516

617
// Read config file path from environment or use default
718
let config_path = env::var("CONFIG_FILE").unwrap_or_else(|_| "config.toml".to_string());
@@ -21,7 +32,17 @@ fn main() {
2132

2233
sim.build_universe();
2334
let result = sim.run();
24-
result.save_tx_graph("graph.svg");
35+
if let Some(dir) = args.artifacts_dir.as_ref() {
36+
std::fs::create_dir_all(dir).unwrap();
37+
let graph_path = dir.join("graph.svg");
38+
let results_path = dir.join("results.json");
39+
let config_out_path = dir.join("config.toml");
40+
result.save_tx_graph(graph_path);
41+
result.save_results_json(results_path);
42+
std::fs::copy(&config_path, config_out_path).unwrap();
43+
} else {
44+
result.save_tx_graph("graph.svg");
45+
}
2546
println!(
2647
"Total payment obligations: {}",
2748
result.total_payment_obligations()

0 commit comments

Comments
 (0)