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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
- [BREAKING] Renamed `SubmitProvenBatch` RPC endpoint to `SubmitProvenTxBatch` ([#2094](https://github.com/0xMiden/node/pull/2094)).
- Fixed block producer mempool panic when selecting transactions that depend on notes created by pruned committed transactions ([#2097](https://github.com/0xMiden/node/pull/2097)).

- [BREAKING] Renamed `ExplorerStatusDetails` fields in the network monitor's `/status` payload from `number_of_*` to `total_*` (`total_transactions`, `total_nullifiers`, `total_notes`, `total_account_updates`). The values now represent network-wide cumulative totals from the explorer's `overviewStats` query instead of last-block counts.
- [BREAKING] Removed `--wallet-filepath` / `--counter-filepath` flags and the `MIDEN_MONITOR_WALLET_FILEPATH` / `MIDEN_MONITOR_COUNTER_FILEPATH` env vars from the network monitor. The monitor now keeps wallet and counter accounts fully in memory and regenerates them on every startup; the dashboard's counter value resets to zero on restart.
- Added `--counter-pending-unhealthy-threshold` (env `MIDEN_MONITOR_COUNTER_PENDING_UNHEALTHY_THRESHOLD`, default `5`) to the network monitor: the Network Transactions card now flips unhealthy when the gap between expected and observed counter values stays above the threshold for three consecutive polls.
## v0.14.11 (TBD)

- Replaced blocking-in-async operations in the validator, remote prover, and ntx-builder with `spawn_blocking` to avoid starving the Tokio runtime ([#2041](https://github.com/0xMiden/node/pull/2041)).
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 0 additions & 2 deletions bin/network-monitor/.env
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ MIDEN_MONITOR_FAUCET_URL=https://faucet-api.devnet.miden.io/
MIDEN_MONITOR_FAUCET_TEST_INTERVAL=2m
# network transaction checks
MIDEN_MONITOR_DISABLE_NTX_SERVICE=false
MIDEN_MONITOR_COUNTER_FILEPATH=counter_account.mac
MIDEN_MONITOR_WALLET_FILEPATH=wallet_account.mac
MIDEN_MONITOR_COUNTER_INCREMENT_INTERVAL=30s
MIDEN_MONITOR_COUNTER_LATENCY_TIMEOUT=2m
# explorer checks
Expand Down
49 changes: 25 additions & 24 deletions bin/network-monitor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,28 @@ version.workspace = true
workspace = true

[dependencies]
anyhow = { workspace = true }
axum = { version = "0.8" }
clap = { features = ["env"], workspace = true }
hex = { workspace = true }
humantime = { workspace = true }
maud = { features = ["axum"], version = "0.27" }
miden-node-proto = { workspace = true }
miden-node-utils = { workspace = true }
miden-protocol = { features = ["std", "testing"], workspace = true }
miden-standards = { workspace = true }
miden-testing = { workspace = true }
miden-tx = { features = ["concurrent", "std"], workspace = true }
rand = { workspace = true }
rand_chacha = { workspace = true }
reqwest = { features = ["json", "query"], workspace = true }
serde = { workspace = true }
serde_json = { version = "1.0" }
sha2 = { workspace = true }
time = { features = ["formatting", "macros"], version = "0.3" }
tokio = { features = ["full"], workspace = true }
tonic = { features = ["codegen", "tls-native-roots", "transport"], workspace = true }
tonic-health = { workspace = true }
tracing = { workspace = true }
url = { features = ["serde"], workspace = true }
anyhow = { workspace = true }
axum = { version = "0.8" }
clap = { features = ["env"], workspace = true }
hex = { workspace = true }
humantime = { workspace = true }
maud = { features = ["axum"], version = "0.27" }
miden-node-proto = { workspace = true }
miden-node-utils = { workspace = true }
miden-protocol = { features = ["std", "testing"], workspace = true }
miden-standards = { workspace = true }
miden-testing = { workspace = true }
miden-tx = { features = ["concurrent", "std"], workspace = true }
rand = { workspace = true }
rand_chacha = { workspace = true }
reqwest = { features = ["json", "query"], workspace = true }
serde = { workspace = true }
serde_json = { version = "1.0" }
serde_path_to_error = { version = "0.1" }
sha2 = { workspace = true }
time = { features = ["formatting", "macros"], version = "0.3" }
tokio = { features = ["full"], workspace = true }
tonic = { features = ["codegen", "tls-native-roots", "transport"], workspace = true }
tonic-health = { workspace = true }
tracing = { workspace = true }
url = { features = ["serde"], workspace = true }
70 changes: 23 additions & 47 deletions bin/network-monitor/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ miden-network-monitor start --faucet-url http://localhost:8080 --enable-otel
- `--stale-chain-tip-threshold`: Maximum time without a chain tip update before marking RPC as unhealthy (default: `1m`)
- `--port, -p`: Web server port (default: `3000`)
- `--enable-otel`: Enable OpenTelemetry tracing
- `--wallet-filepath`: Path where the wallet account is located (default: `wallet_account.mac`)
- `--counter-filepath`: Path where the network account is located (default: `counter_program.mac`)
- `--counter-increment-interval`: Interval at which to send the increment counter transaction (default: `30s`)
- `--counter-pending-unhealthy-threshold`: Mark the Network Transactions card unhealthy when the gap between expected and observed counter values stays above this for several consecutive polls (default: `5`)
- `--counter-latency-timeout`: Maximum time to wait for a counter update after submitting a transaction (default: `2m`)
- `--help, -h`: Show help information
- `--version, -V`: Show version information
Expand All @@ -68,9 +67,8 @@ If command-line arguments are not provided, the application falls back to enviro
- `MIDEN_MONITOR_STALE_CHAIN_TIP_THRESHOLD`: Maximum time without a chain tip update before marking RPC as unhealthy
- `MIDEN_MONITOR_PORT`: Web server port
- `MIDEN_MONITOR_ENABLE_OTEL`: Enable OpenTelemetry tracing
- `MIDEN_MONITOR_WALLET_FILEPATH`: Path where the wallet account is located
- `MIDEN_MONITOR_COUNTER_FILEPATH`: Path where the network account is located
- `MIDEN_MONITOR_COUNTER_INCREMENT_INTERVAL`: Interval at which to send the increment counter transaction
- `MIDEN_MONITOR_COUNTER_PENDING_UNHEALTHY_THRESHOLD`: Mark the Network Transactions card unhealthy when the gap between expected and observed counter values stays above this for several consecutive polls
- `MIDEN_MONITOR_COUNTER_LATENCY_TIMEOUT`: Maximum time to wait for a counter update after submitting a transaction

## Commands
Expand All @@ -96,20 +94,17 @@ miden-network-monitor start
--port 8080 \
--rpc.url "http://localhost:50051"

# Enable network transaction service (both increment and tracking) with custom account file paths
# Enable network transaction service (both increment and tracking)
miden-network-monitor start \
--wallet-filepath my_wallet.mac \
--counter-filepath my_network_account.mac \
--rpc-url https://testnet.miden.io:443
```

**Optional Counter Account Management (only when counter is enabled):**
When `--disable-ntx-service=false` or unset, the monitor ensures required network transaction service account exists before starting the task:
1. If file is missing, creates new counter account:
- Network account with the increment procedure
2. Saves network account to the specified file using the Miden `AccountFile` format
3. Deploys accounts to the network via RPC (if not already deployed)
4. The network account contract authorizes increments only from a whitelisted wallet account
**Counter Account Management (only when counter is enabled):**
When `--disable-ntx-service=false` or unset, the monitor creates a fresh wallet and counter
account in memory on every startup, deploys the counter to the network, and holds both
accounts entirely in memory. The accounts are never persisted to disk; restarting the monitor
always provisions new ones, and the counter value on the dashboard restarts from zero. The
counter contract authorizes increments only from the wallet that owns it.

## Usage

Expand All @@ -128,8 +123,6 @@ miden-network-monitor start \
--faucet-test-interval 2m \
--status-check-interval 3s \
--port 8080 \
--wallet-filepath my_wallet.mac \
--counter-filepath my_counter.mac \
--enable-otel

# Get help
Expand All @@ -145,8 +138,6 @@ MIDEN_MONITOR_REMOTE_PROVER_URLS="http://localhost:50052" miden-network-monitor
# Multiple remote provers, faucet testing, and network transaction service
MIDEN_MONITOR_REMOTE_PROVER_URLS="http://localhost:50052,http://localhost:50053,http://localhost:50054" \
MIDEN_MONITOR_FAUCET_URL="http://localhost:8080" \
MIDEN_MONITOR_WALLET_FILEPATH="my_wallet.mac" \
MIDEN_MONITOR_COUNTER_FILEPATH="my_counter.mac" \
MIDEN_MONITOR_DISABLE_NTX_SERVICE=false \
miden-network-monitor start
```
Expand Down Expand Up @@ -269,46 +260,31 @@ The dashboard automatically probes RPC and Remote Prover services every 30 secon

## Account Management

When the network transaction service is enabled, the monitor manages the necessary Miden accounts:
When the network transaction service is enabled, the monitor provisions the necessary Miden
accounts entirely in memory.

### Created Accounts

**Network Account:**
- Implements a simple counter with increment functionality
- Includes authentication logic that restricts access to the network account
- Uses custom MASM script with account ID-based authorization
- Automatically created if not present
- Authorizes increments only from the wallet account that owns it (account ID-based check)
- Uses a custom MASM script

**Wallet Account:**
- Uses RpoFalcon512 authentication scheme
- Contains authentication keys for transaction signing
- Automatically created if not present
- Holds the authentication keys for signing increment transactions

### Account File Management
### Lifecycle

The monitor automatically:
1. Checks for existing account files on startup
2. Creates new accounts if files don't exist
3. Deploys accounts to the network via RPC
4. Saves the wallet and counter contract account in the specified file paths (default: `wallet_account.mac` and `counter_program.mac`)
On every startup the monitor:
1. Generates a fresh wallet/counter account pair in memory.
2. Deploys the counter to the network via RPC.
3. Holds both accounts in memory; they are never written to disk.

### Example Usage

```bash
# Start monitor with counter task and default account files
miden-network-monitor start --rpc-url https://testnet.miden.io:443

# Start monitor with custom account file paths
miden-network-monitor start \
--disable-ntx-service=false \
--rpc-url https://testnet.miden.io:443 \
--wallet-filepath my_wallet.mac \
--counter-filepath my_counter.mac

# The generated files can be loaded in Miden applications:
# - wallet_account.mac: Contains the wallet account with authentication keys
# - counter_program.mac: Contains the counter program account
```
If increment transactions fail repeatedly, the monitor regenerates both accounts in memory
(same flow as startup) and the tracker switches to the new counter automatically. Restarting
the monitor always provisions fresh accounts, so the dashboard's counter value starts at
zero after each restart.

## Future Monitor Items

Expand Down
10 changes: 10 additions & 0 deletions bin/network-monitor/assets/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,16 @@ body {
font-weight: 500;
}

/* When the value carries an inline action (currently only the copy button), keep them on the
same line. Without this `.metric-value` is inline, and the whitespace between the value text
and the button is a wrap opportunity — so long values (URLs in particular) push the button
onto its own row below. */
.metric-value:has(.copy-button) {
display: inline-flex;
align-items: center;
gap: 4px;
}

.metric-value.warning-delta,
.warning-text {
color: var(--color-warning);
Expand Down
2 changes: 1 addition & 1 deletion bin/network-monitor/src/cli/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ impl Cli {
/// Execute the parsed command.
pub async fn execute(self) -> anyhow::Result<()> {
match self.command {
Command::Start(config) => start_monitor(config).await,
Command::Start(config) => Box::pin(start_monitor(config)).await,
}
}
}
31 changes: 12 additions & 19 deletions bin/network-monitor/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
//! This module contains the configuration structures and constants for the network monitor.
//! Configuration for the monitor.

use std::path::PathBuf;
use std::time::Duration;

use clap::Parser;
Expand Down Expand Up @@ -119,24 +118,6 @@ pub struct MonitorConfig {
)]
pub disable_ntx_service: bool,

/// Path for the counter program network account file.
#[arg(
long = "counter-filepath",
env = "MIDEN_MONITOR_COUNTER_FILEPATH",
default_value = "counter_program.mac",
help = "Path where the counter account is located"
)]
pub counter_filepath: PathBuf,

/// Path for the wallet account file.
#[arg(
long = "wallet-filepath",
env = "MIDEN_MONITOR_WALLET_FILEPATH",
default_value = "wallet_account.mac",
help = "Path where the wallet account is located"
)]
pub wallet_filepath: PathBuf,

/// The interval at which to send the increment counter transaction.
#[arg(
long = "counter-increment-interval",
Expand All @@ -157,6 +138,18 @@ pub struct MonitorConfig {
)]
pub counter_latency_timeout: Duration,

/// Maximum allowed gap between the expected and observed counter values before the Network
/// Transactions card is flipped to unhealthy. A small backlog while transactions are in flight
/// is expected; this threshold guards against the network silently dropping notes.
#[arg(
long = "counter-pending-unhealthy-threshold",
env = "MIDEN_MONITOR_COUNTER_PENDING_UNHEALTHY_THRESHOLD",
default_value_t = 5,
help = "Mark the counter card unhealthy when the gap between expected and observed values \
stays above this threshold for several consecutive polls"
)]
pub counter_pending_unhealthy_threshold: u64,

/// The timeout for the outgoing requests.
#[arg(
long = "request-timeout",
Expand Down
Loading
Loading