Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 88 additions & 14 deletions packages/devkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,107 @@ Developer toolkit for the Stellar Fee Tracker. Provides utilities for testing, m

## Simulation

The `simulation` module provides fee modelling and network-load generation without any live-network dependencies.
The `simulation` module provides fee modelling, network-load generation, and congestion prediction without any live-network dependencies.

### `FeeModelConfig` fields

| Field | Type | Description |
|---|---|---|
| `base_fee` | `u64` | Minimum fee (stroops) used as the simulation floor |
| `surge_multiplier` | `f64` | Fee multiplier applied when the network is congested |
| `congestion_threshold` | `f64` | Load ratio (0.0–1.0) above which surge pricing activates |
| Field | Type | Default | Description |
|---|---|---|---|
| `base_fee` | `u64` | `100` | Base fee in stroops |
| `spike_probability` | `f64` | `0.05` | Probability that any given ledger is a spike (0.0–1.0) |
| `spike_multiplier` | `u64` | `10` | Multiplier applied to `base_fee` during a spike |
| `ledger_interval_secs` | `u64` | `5` | Seconds between simulated ledgers |
| `ledger_count` | `u64` | `100` | Number of ledgers to generate per `run()` call |
| `seed` | `Option<u64>` | `None` | RNG seed for reproducible output |
| `noise_factor` | `f64` | `0.0` | Gaussian noise stddev as a fraction of `base_fee` |

### `NetworkLoadConfig` fields

| Field | Type | Default | Description |
|---|---|---|---|
| `min_tx` | `u64` | `10` | Minimum transactions per ledger |
| `max_tx` | `u64` | `1000` | Maximum transactions per ledger |
| `ledger_capacity` | `u64` | `1000` | Maximum tx capacity per ledger |
| `ledger_interval_ms` | `u64` | `5000` | Time between ledger closes in ms |
| `seed` | `Option<u64>` | `None` | RNG seed for reproducibility |

### Example usage

```rust
use stellar_devkit::simulation::{FeeModel, NetworkLoad};
use stellar_devkit::simulation::fee_model::{FeeModel, FeeModelConfig};
use stellar_devkit::simulation::network_load::{NetworkLoad, NetworkLoadConfig};
use stellar_devkit::simulation::congestion_predictor::{CongestionPredictor, CongestionInput, congestion_label};

// Configure a fee scenario
let fee_cfg = FeeModelConfig {
base_fee: 100,
spike_probability: 0.1,
spike_multiplier: 5,
seed: Some(42),
..FeeModelConfig::default()
};

let load = NetworkLoad::constant(0.85); // 85 % utilisation
let result = FeeModel::run(&load, base_fee: 100, surge_multiplier: 2.0, congestion_threshold: 0.8);
println!("recommended fee: {} stroops", result.recommended_fee);
// Generate fee points
let points = FeeModel::run(&fee_cfg);
println!("Generated {} fee points", points.len());

// Configure network load
let load_cfg = NetworkLoadConfig {
min_tx: 50,
max_tx: 800,
ledger_capacity: 1000,
seed: Some(7),
..NetworkLoadConfig::default()
};
let mut load = NetworkLoad::new(load_cfg);
let ledgers = load.simulate(10);

// Predict congestion
let label = congestion_label(&CongestionInput {
recent_fee_window: 250.0,
capacity_usage: 0.75,
spike_count: 3,
});
println!("Congestion: {:?}", label);
```

### Output format (`SimResult`)
### Output format (`FeePoint`)

Each `FeePoint` represents a single simulated ledger:

| Field | Type | Description |
|---|---|---|
| `recommended_fee` | `u64` | Suggested fee for the simulated conditions |
| `congested` | `bool` | Whether surge pricing was triggered |
| `load_ratio` | `f64` | Network utilisation at simulation time |
| `timestamp` | `u64` | Simulated Unix timestamp (seconds) |
| `fee` | `u64` | Fee in stroops for this ledger |
| `ledger` | `u64` | Ledger sequence number (1-based) |
| `is_spike` | `bool` | Whether this ledger was a spike |

### CSV export

Fee points can be exported to CSV via the CLI:

```bash
cargo run --bin devkit -- export ./fees.db --output fees.csv
```

The CSV format matches the `FeePoint` shape:

```
timestamp,fee,ledger,is_spike
1700000000,100,1,false
1700000005,500,2,true
1700000010,110,3,false
```

For programmatic export, serialise `FeePoint` slices directly:

```rust
use stellar_devkit::simulation::fee_model::{FeeModel, FeeModelConfig, FeeCurve};

let points = FeeModel::run(&FeeModelConfig::default());
let json = FeeCurve::fee_points_to_json(&points, 100)?;
println!("{}", json);
```

## Running

Expand Down
Loading
Loading