Replayer
The replayer is a specialized debugging tool that enables deterministic recording and replay of node execution. It captures the complete state machine behavior of a running node, allowing developers to reproduce and debug issues with perfect accuracy.
What is a replayer node?
A replayer node is not a separate node type, but rather a mode of operation that allows you to:
- Record execution: Capture initial state and all input actions during node operation
- Deterministic replay: Reproduce the exact sequence of state transitions offline
- Debug issues: Analyze problematic behavior by replaying recorded execution
- Verify behavior: Ensure state machine transitions remain consistent across code changes
How it works
The replayer operates in two phases:
1. Recording phase
During normal node operation with recording enabled:
- Initial node state is serialized to disk
- All input actions (events that trigger state changes) are logged with metadata
- Effect actions (side effects dispatched by reducers) are tracked
- Data is stored in the
recorder/directory within the working directory
2. Replay phase
During replay:
- Initial state is loaded from the recording
- Input actions are dispatched in the exact order they occurred
- The replayer verifies that effect actions match the recording
- Any mismatches indicate non-deterministic behavior or code changes
Use cases
- Bug reproduction: Capture a failing node execution and replay it locally for debugging
- Regression testing: Ensure state machine behavior remains consistent after code changes
- Performance analysis: Analyze state transitions without network I/O overhead
- CI/CD validation: Automated testing of recorded scenarios in continuous integration
The replayer requires that the node's state machine is deterministic. Any non-deterministic behavior (random number generation without proper seeding, system time calls, etc.) will cause replay validation to fail.
The Mina node architecture uses a seeded RNG and controlled time sources to ensure deterministic behavior.
Recording node execution
To record a node's execution, use the --record flag with the
state-with-input-actions mode.
Basic recording
- From Source
- Using Docker
#!/bin/bash
# Record node execution for debugging and replay
# Run node with recording enabled
mina node \
--network devnet \
--record state-with-input-actions \
--work-dir ~/.mina-replay-test
#!/bin/bash
# Record node execution using Docker
# Create directory for recording
mkdir -p mina-replay-test
# Run node with recording enabled using Docker
docker run --rm \
-v "$(pwd)/mina-replay-test:/root/.mina" \
o1labs/mina-rust:latest \
node \
--network devnet \
--record state-with-input-actions \
--work-dir /root/.mina
This will:
- Start a node connected to devnet
- Record all state and actions to the
recorder/directory - Run until manually stopped (Ctrl+C)
Recording with custom directory
- From Source
- Using Docker
#!/bin/bash
# Record node execution with custom working directory
WORK_DIR="$1"
if [ -z "$WORK_DIR" ]; then
echo "Usage: $0 <work-directory>"
exit 1
fi
# Run node with recording enabled using custom directory
mina node \
--network devnet \
--record state-with-input-actions \
--work-dir "$WORK_DIR"
#!/bin/bash
# Record with custom directory using Docker
# Create custom directory for recording
mkdir -p my-custom-replay-dir
# Run node with custom recording directory
docker run --rm \
-v "$(pwd)/my-custom-replay-dir:/root/.mina" \
o1labs/mina-rust:latest \
node \
--network devnet \
--record state-with-input-actions \
--work-dir /root/.mina
Recording options
The --record parameter accepts the following values:
none: No recording (default)state-with-input-actions: Records initial state and all input actions
Recorded data structure
When recording is enabled, data is stored in the following structure:
<work-dir>/recorder
├──actions_1.postcard
├──actions_2.postcard
├──actions_3.postcard
|──actions_4.postcard
├──actions_5.postcard
├──actions_6.postcard
├──actions_7.postcard
|──actions_8.postcard
└──initial_state.postcard
Recording can generate significant data over time. Monitor disk space usage when running with recording enabled for extended periods.
Replaying recorded execution
Once you have recorded node execution, you can replay it using the mina replay
command.
Basic replay
- From Source
- Using Docker
#!/bin/bash
# Replay recorded node execution
# Replay from the recorded directory
mina replay state-with-input-actions --dir ~/.mina-replay-test/recorder
#!/bin/bash
# Replay recorded node execution using Docker
# Replay from the recorded directory
docker run --rm \
-v "$(pwd)/mina-replay-test:/root/.mina" \
o1labs/mina-rust:latest \
replay state-with-input-actions --dir /root/.mina/recorder
This will:
- Load the initial state from the recording
- Dispatch all recorded actions in order
- Verify that effect actions match the recording
- Exit when all actions have been replayed
Replay with build environment checking
By default, replay validates that the recorded build environment matches the current build. To ignore mismatches (useful when testing code changes):
- From Source
- Using Docker
#!/bin/bash
# Replay and ignore build environment differences
mina replay state-with-input-actions \
--dir ~/.mina-replay-test/recorder \
--ignore-mismatch
#!/bin/bash
# Replay with build environment mismatch ignored using Docker
docker run --rm \
-v "$(pwd)/mina-replay-test:/root/.mina" \
o1labs/mina-rust:latest \
replay state-with-input-actions \
--dir /root/.mina/recorder \
--ignore-build-env-mismatch
Replay with dynamic effects
For advanced debugging, you can inject custom effect handlers during replay:
- From Source
- Using Docker
#!/bin/bash
# Build custom effects library and replay with custom effects
# Build custom effects library
cargo build --release -p replay_dynamic_effects
# Replay with custom effects
mina replay state-with-input-actions \
--dir ~/.mina-replay-test/recorder \
--dynamic-effects-lib ./target/release/libreplay_dynamic_effects.so
#!/bin/bash
# Replay with dynamic effects using Docker
docker run --rm \
-v "$(pwd)/mina-replay-test:/root/.mina" \
-v "$(pwd)/my-effects.so:/effects/my-effects.so" \
o1labs/mina-rust:latest \
replay state-with-input-actions \
--dir /root/.mina/recorder \
--dynamic-effects-lib /effects/my-effects.so
Custom effects allow you to:
- Inspect state at specific points during replay
- Modify behavior for debugging purposes
- Hot-reload the effects library without restarting replay