sim-cli 0.7.0

CLI tool for running and comparing Solana simulator backtests
Documentation
//! Domain and report types shared across the compare pipeline.

use serde::{Deserialize, Serialize};

use crate::output::{SolChange, TokenChange};

/// Slim projection the join needs; log content and account diffs are never loaded.
#[derive(Serialize, Deserialize)]
pub(super) struct CompareTransaction {
    pub(super) slot: u64,
    pub(super) signature: String,
    pub(super) success: bool,
    pub(super) error: Option<String>,
    pub(super) log_count: usize,
    pub(super) sol_changes: Vec<SolChange>,
    pub(super) token_changes: Vec<TokenChange>,
}

#[derive(Serialize, Clone)]
pub(super) struct SolDiff {
    pub(super) pubkey: String,
    // deltas are pre/post sol balances
    pub(super) baseline_delta: i64,
    pub(super) experiment_delta: i64,
}

#[derive(Serialize, Clone)]
pub(super) struct SplDiff {
    pub(super) pubkey: String,
    pub(super) mint: String,
    #[serde(skip_serializing_if = "String::is_empty")]
    pub(super) symbol: String,
    pub(super) decimals: u8,
    // deltas are pre/post token balances
    pub(super) baseline_delta: i64,
    pub(super) experiment_delta: i64,
}

#[derive(Serialize, Clone)]
pub(super) struct PnlDiff {
    pub(super) slot: u64,
    pub(super) signature: String,
    pub(super) sol: Vec<SolDiff>,
    pub(super) tokens: Vec<SplDiff>,
    // affects how the the pnl diffs are ranked and surfaced to user
    #[serde(skip)]
    pub(super) score: f64,
}

#[derive(Serialize)]
pub(super) struct RegressionEntry {
    pub(super) slot: u64,
    pub(super) signature: String,
    pub(super) error: Option<String>,
}

#[derive(Serialize)]
pub(super) struct ImprovementEntry {
    pub(super) slot: u64,
    pub(super) signature: String,
    pub(super) was: Option<String>,
}

#[derive(Serialize)]
pub(super) struct LogDiffEntry {
    pub(super) slot: u64,
    pub(super) signature: String,
    pub(super) baseline_log_count: usize,
    pub(super) experiment_log_count: usize,
}

#[derive(Serialize)]
pub(super) struct CompareOutput {
    pub(super) baseline: String,
    pub(super) experiment: String,
    pub(super) baseline_transactions: usize,
    pub(super) experiment_transactions: usize,
    pub(super) common_transactions: usize,
    pub(super) regressions: Vec<RegressionEntry>,
    pub(super) improvements: Vec<ImprovementEntry>,
    pub(super) log_diffs: Vec<LogDiffEntry>,
    pub(super) missing: Vec<String>,
    pub(super) balance_diffs: Vec<PnlDiff>,
    pub(super) summary: CompareSummary,
}

#[derive(Serialize)]
pub(super) struct CompareSummary {
    pub(super) regressions: usize,
    pub(super) improvements: usize,
    pub(super) log_diffs: usize,
    pub(super) missing: usize,
    pub(super) balance_diffs: usize,
}

/// Memory scales with the number of differences, not input size.
#[derive(Serialize)]
pub(super) struct CompareReport {
    pub(super) baseline_transactions: usize,
    pub(super) experiment_transactions: usize,
    pub(super) common: usize,
    pub(super) regressions: Vec<RegressionEntry>,
    pub(super) improvements: Vec<ImprovementEntry>,
    pub(super) log_diffs: Vec<LogDiffEntry>,
    pub(super) missing: Vec<String>,
    pub(super) pnl_diffs: Vec<PnlDiff>,
}