You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Deterministic Simulation Testing (DST) is a technique for testing distributed systems by simulating chaotic interactions — network delays, message reordering, process crashes — over extended periods of simulated time. The system randomly explores a vast state space, but every choice flows from a single RNG seed, meaning any failure can be perfectly replayed.
Why DST for EastGuard?
Our SWIM protocol implementation has several sources of non-determinism that make bugs hard to reproduce:
Timer-driven logic: SwimActor relies on tokio::time::interval and tokio::spawn + time::sleep for protocol ticks, ACK timeouts, and suspect timeouts. The exact interleaving of these timers is unpredictable.
Random peer selection: StdRng::from_entropy() makes probe targets non-reproducible across runs.
UDP transport: TransportLayer binds a real UdpSocket, so tests require actual network I/O with all its timing variability.
DST addresses this by giving us:
Reproducibility: A single seed reproduces the exact execution path — network delays, peer selection order, timeout interleaving. Heisenbugs become reproducible on any machine.
Failure injection: We can simulate packet loss, reordering, and node crashes to verify that SWIM correctly detects failures, refutes false suspicions, and converges membership state.
Early detection: Complex issues like gossip not propagating or incorrect incarnation handling surface during seed-fuzzing, not in production.
How to Introduce DST
Step 1: Make SwimActor a pure state machine
Decouple protocol logic from the async runtime, following tikv/raft-rs's pattern:
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Deterministic Simulation Testing (DST) Proposal
What is DST?
Deterministic Simulation Testing (DST) is a technique for testing distributed systems by simulating chaotic interactions — network delays, message reordering, process crashes — over extended periods of simulated time. The system randomly explores a vast state space, but every choice flows from a single RNG seed, meaning any failure can be perfectly replayed.
Why DST for EastGuard?
Our SWIM protocol implementation has several sources of non-determinism that make bugs hard to reproduce:
SwimActorrelies ontokio::time::intervalandtokio::spawn+time::sleepfor protocol ticks, ACK timeouts, and suspect timeouts. The exact interleaving of these timers is unpredictable.StdRng::from_entropy()makes probe targets non-reproducible across runs.TransportLayerbinds a realUdpSocket, so tests require actual network I/O with all its timing variability.DST addresses this by giving us:
How to Introduce DST
Step 1: Make SwimActor a pure state machine
Decouple protocol logic from the async runtime, following tikv/raft-rs's pattern:
The actor owns no channels, spawns no tasks, and calls no async functions. A thin driver (
run_swim) handles I/O in production.Step 2: Control all sources of non-determinism
start_paused = trueStdRng::from_entropy()StdRng::seed_from_u64(seed)injected at constructionstd::time::Instant, real sleepstokio::time::Instantwith paused time; time only advances on explicittokio::time::advance()UdpSocketinTransportLayerRandomStateorBTreeMapfor deterministic iterationStep 3: Build an in-memory network simulator
Replace
TransportLayerwith a simulator that models packet delivery:The simulator decides per-packet whether to deliver, delay, reorder, or drop — all seeded from the same RNG.
Step 4: Verification
TRACE-level logs byte-for-byte — they must be identical.References
All reactions