moonpool_sim/chaos/fault_events.rs
1//! Simulator-emitted fault events for the event timeline.
2//!
3//! When faults are injected (network partitions, process reboots, storage corruption, etc.),
4//! the simulator automatically emits [`SimFaultEvent`]s to the [`SIM_FAULT_TIMELINE`] timeline.
5//! Invariants can read these to correlate application behavior with infrastructure faults.
6//!
7//! # Usage
8//!
9//! ```ignore
10//! use moonpool_sim::{Invariant, StateHandle, SimFaultEvent, SIM_FAULT_TIMELINE};
11//!
12//! fn check(state: &StateHandle, _sim_time_ms: u64) {
13//! if let Some(faults) = state.timeline::<SimFaultEvent>(SIM_FAULT_TIMELINE) {
14//! for entry in faults.all().iter() {
15//! match &entry.event {
16//! SimFaultEvent::ProcessForceKill { ip } => { /* ... */ }
17//! _ => {}
18//! }
19//! }
20//! }
21//! }
22//! ```
23
24/// Well-known timeline key for simulator-emitted fault events.
25pub const SIM_FAULT_TIMELINE: &str = "sim:faults";
26
27/// Fault events automatically emitted by the simulator.
28///
29/// Read via `state.timeline::<SimFaultEvent>(SIM_FAULT_TIMELINE)` in invariants.
30#[derive(Debug, Clone)]
31pub enum SimFaultEvent {
32 // -- Process lifecycle --
33 /// Process graceful shutdown initiated.
34 ProcessGracefulShutdown {
35 /// IP address of the process.
36 ip: String,
37 /// Grace period before force-kill, in milliseconds.
38 grace_period_ms: u64,
39 },
40 /// Process force-killed.
41 ProcessForceKill {
42 /// IP address of the process.
43 ip: String,
44 },
45 /// Process restarted after recovery delay.
46 ProcessRestart {
47 /// IP address of the process.
48 ip: String,
49 },
50
51 // -- Network --
52 /// Bidirectional network partition created between two IPs.
53 PartitionCreated {
54 /// Source IP.
55 from: String,
56 /// Destination IP.
57 to: String,
58 },
59 /// Network partition healed between two IPs.
60 PartitionHealed {
61 /// Source IP.
62 from: String,
63 /// Destination IP.
64 to: String,
65 },
66 /// Connection temporarily cut.
67 ConnectionCut {
68 /// The connection that was cut.
69 connection_id: u64,
70 /// Duration of the cut in milliseconds.
71 duration_ms: u64,
72 },
73 /// Temporarily cut connection restored.
74 CutRestored {
75 /// The connection that was restored.
76 connection_id: u64,
77 },
78 /// Half-open connection error triggered.
79 HalfOpenError {
80 /// The connection now returning errors.
81 connection_id: u64,
82 },
83 /// Send partition created (blocks outgoing from an IP).
84 SendPartitionCreated {
85 /// The partitioned IP.
86 ip: String,
87 },
88 /// Receive partition created (blocks incoming to an IP).
89 RecvPartitionCreated {
90 /// The partitioned IP.
91 ip: String,
92 },
93 /// Connection randomly closed by chaos.
94 RandomClose {
95 /// The connection that was closed.
96 connection_id: u64,
97 },
98 /// Peer crash simulated (half-open connection created).
99 PeerCrash {
100 /// The connection now in half-open state.
101 connection_id: u64,
102 },
103 /// Bit flip corruption injected during data delivery.
104 BitFlip {
105 /// The connection carrying corrupted data.
106 connection_id: u64,
107 /// Number of bits flipped.
108 flip_count: usize,
109 },
110
111 // -- Storage --
112 /// Read fault injected (sector marked as faulted).
113 StorageReadFault {
114 /// IP of the process owning the file.
115 ip: String,
116 /// File identifier.
117 file_id: u64,
118 },
119 /// Write fault injected (phantom, misdirected, or corruption).
120 StorageWriteFault {
121 /// IP of the process owning the file.
122 ip: String,
123 /// File identifier.
124 file_id: u64,
125 /// Kind of write fault: "phantom", "misdirected", or "corruption".
126 kind: String,
127 },
128 /// Sync failure injected.
129 StorageSyncFault {
130 /// IP of the process owning the file.
131 ip: String,
132 /// File identifier.
133 file_id: u64,
134 },
135 /// Storage crash simulated for a process.
136 StorageCrash {
137 /// IP of the crashed process.
138 ip: String,
139 },
140 /// All storage wiped for a process (CrashAndWipe reboot).
141 StorageWipe {
142 /// IP of the wiped process.
143 ip: String,
144 },
145}