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
11 changes: 6 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -167,11 +167,12 @@ jobs:
cargo run --bin miden-node-stress-test seed-store \
--data-directory ${{ env.DATA_DIR }} \
--num-accounts 500 --public-accounts-percentage 50
- name: Benchmark state sync
run: |
cargo run --bin miden-node-stress-test benchmark-store \
--data-directory ${{ env.DATA_DIR }} \
--iterations 10 --concurrency 1 sync-state
# TODO re-introduce
# - name: Benchmark state sync
# run: |
# cargo run --bin miden-node-stress-test benchmark-store \
# --data-directory ${{ env.DATA_DIR }} \
# --iterations 10 --concurrency 1 sync-state
- name: Benchmark notes sync
run: |
cargo run --bin miden-node-stress-test benchmark-store \
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,13 @@

- [BREAKING] Move block proving from Blocker Producer to the Store ([#1579](https://github.com/0xMiden/miden-node/pull/1579)).
- [BREAKING] Updated miden-base dependencies to use `next` branch; renamed `NoteInputs` to `NoteStorage`, `.inputs()` to `.storage()`, and database `inputs` column to `storage` ([#1595](https://github.com/0xMiden/miden-node/pull/1595)).
- [BREAKING] Remove `SynState` and introduce `SyncChainMmr` ([#1591](https://github.com/0xMiden/miden-node/issues/1591)).
- Introduce `SyncChainMmr` RPC endpoint to sync chain MMR deltas within specified block ranges ([#1591](https://github.com/0xMiden/miden-node/issues/1591)).

### Changes

- [BREAKING] Removed obsolete `SyncState` RPC endpoint; clients should use `SyncNotes`, `SyncNullifiers`, `SyncAccountVault`, `SyncAccountStorageMaps`, `SyncTransactions`, or `SyncChainMmr` instead ([#1636](https://github.com/0xMiden/miden-node/pull/1636)).
- Added account ID limits for `SyncTransactions`, `SyncAccountVault`, and `SyncAccountStorageMaps` to `GetLimits` responses ([#1636](https://github.com/0xMiden/miden-node/pull/1636)).
- [BREAKING] Added typed `GetAccountError` for `GetAccount` endpoint, splitting `BlockNotAvailable` into `UnknownBlock` and `BlockPruned`. `AccountNotFound` and `AccountNotPublic` now return `InvalidArgument` gRPC status instead of `NotFound`; clients should parse the error details discriminant rather than branching on status codes ([#1646](https://github.com/0xMiden/miden-node/pull/1646)).
- Changed `note_type` field in proto `NoteMetadata` from `uint32` to a `NoteType` enum ([#1594](https://github.com/0xMiden/miden-node/pull/1594)).
- Refactored NTX Builder startup and introduced `NtxBuilderConfig` with configurable parameters ([#1610](https://github.com/0xMiden/miden-node/pull/1610)).
Expand Down
32 changes: 18 additions & 14 deletions bin/stress-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ This command allows to run stress tests against the Store component. These tests

The endpoints that you can test are:
- `load_state`
- `sync_state`
- `sync_notes`
- `sync_nullifiers`
- `sync_transactions`
- `sync-chain-mmr`

Most benchmarks accept options to control the number of iterations and concurrency level. The `load_state` endpoint is different - it simply measures the one-time startup cost of loading the state from disk.

**Note on Concurrency**: For the endpoints that support it (`sync_state`, `sync_notes`, `sync_nullifiers`), the concurrency parameter controls how many requests are sent in parallel to the store. Since these benchmarks run against a local store (no network overhead), higher concurrency values can help identify bottlenecks in the store's internal processing. The latency measurements exclude network time and represent pure store processing time.
**Note on Concurrency**: For the endpoints that support it (`sync_notes`, `sync_nullifiers`), the concurrency parameter controls how many requests are sent in parallel to the store. Since these benchmarks run against a local store (no network overhead), higher concurrency values can help identify bottlenecks in the store's internal processing. The latency measurements exclude network time and represent pure store processing time.

Example usage:

Expand Down Expand Up @@ -119,18 +119,6 @@ Database contains 99961 accounts and 99960 nullifiers

**Performance Note**: The load-state benchmark shows that account tree loading (~21.3s) and nullifier tree loading (~21.5s) are the primary bottlenecks, while MMR loading and database connection are negligible (<3ms each).

- sync-state
``` bash
$ miden-node-stress-test benchmark-store --data-directory ./data --iterations 10000 --concurrency 16 sync-state

Average request latency: 1.120061ms
P50 request latency: 1.106042ms
P95 request latency: 1.530708ms
P99 request latency: 1.919209ms
P99.9 request latency: 5.795125ms
Average notes per response: 1.3159
```

- sync-notes
``` bash
$ miden-node-stress-test benchmark-store --data-directory ./data --iterations 10000 --concurrency 16 sync-notes
Expand Down Expand Up @@ -171,5 +159,21 @@ Pagination statistics:
Average pages per run: 2.00
```

- sync-chain-mmr
``` bash
$ miden-node-stress-test benchmark-store --data-directory ./data --iterations 10000 --concurrency 16 sync-chain-mmr --block-range 1000

Average request latency: 1.021ms
P50 request latency: 0.981ms
P95 request latency: 1.412ms
P99 request latency: 1.822ms
P99.9 request latency: 3.174ms
Pagination statistics:
Total runs: 10000
Runs triggering pagination: 1
Pagination rate: 0.01%
Average pages per run: 1.00
```

## License
This project is [MIT licensed](../../LICENSE).
16 changes: 10 additions & 6 deletions bin/stress-test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ use clap::{Parser, Subcommand};
use miden_node_utils::logging::OpenTelemetry;
use seeding::seed_store;
use store::{
bench_sync_chain_mmr,
bench_sync_notes,
bench_sync_nullifiers,
bench_sync_state,
bench_sync_transactions,
load_state,
};
Expand Down Expand Up @@ -70,8 +70,6 @@ pub enum Endpoint {
#[arg(short, long, value_name = "PREFIXES", default_value = "10")]
prefixes: usize,
},
#[command(name = "sync-state")]
SyncState,
#[command(name = "sync-notes")]
SyncNotes,
#[command(name = "sync-transactions")]
Expand All @@ -83,6 +81,12 @@ pub enum Endpoint {
#[arg(short, long, value_name = "BLOCK_RANGE", default_value = "100")]
block_range: u32,
},
#[command(name = "sync-chain-mmr")]
SyncChainMmr {
/// Block range size for each request (number of blocks to query).
#[arg(short, long, value_name = "BLOCK_RANGE", default_value = "1000")]
block_range: u32,
},
#[command(name = "load-state")]
LoadState,
}
Expand Down Expand Up @@ -111,9 +115,6 @@ async fn main() {
Endpoint::SyncNullifiers { prefixes } => {
bench_sync_nullifiers(data_directory, iterations, concurrency, prefixes).await;
},
Endpoint::SyncState => {
bench_sync_state(data_directory, iterations, concurrency).await;
},
Endpoint::SyncNotes => {
bench_sync_notes(data_directory, iterations, concurrency).await;
},
Expand All @@ -127,6 +128,9 @@ async fn main() {
)
.await;
},
Endpoint::SyncChainMmr { block_range } => {
bench_sync_chain_mmr(data_directory, iterations, concurrency, block_range).await;
},
Endpoint::LoadState => {
load_state(&data_directory).await;
},
Expand Down
Loading
Loading