Problem
Three issues in crates/storage/src/store.rs:
1. ORDER BY violates DAG ordering (CRITICAL)
history() uses ORDER BY timestamp_hint_ms DESC, seq DESC (line 120). sync_since() uses ORDER BY seq ASC (line 164). Neither respects the DAG's topological order. Peers syncing from storage may receive events in wrong order, causing InsertError::SeqGap or state corruption.
The spec requires events to be returned in topological order (causal parents before dependents).
2. No disk size limit (CRITICAL)
Events are inserted indefinitely with no eviction or size limit. A storage node can fill the entire disk and crash with no graceful degradation.
3. Corrupt events silently skipped (CRITICAL)
All deserialization uses .ok() filter:
let events: Vec<Event> = rows.iter()
.filter_map(|data| bincode::deserialize(data).ok())
.collect();
Corrupted events are silently dropped — no logging, no alerting. Query returns fewer events than expected with no indication of data loss.
Impact
- Peers receive events out of topological order → state corruption
- Disk exhaustion → crash with no recovery
- Silent data loss from corruption → incomplete state for syncing peers
Suggested fix
- Return events via
EventDag::topological_sort() order, or store a topo-sort index
- Add
--max-events or --max-size-gb config with oldest-event eviction
- Log warnings on deserialization failures; add corruption counter metric
Location
crates/storage/src/store.rs:120,164-165,206-207 (ordering)
crates/storage/src/store.rs entire (disk limit)
crates/storage/src/store.rs:143,175,224 (deserialization)
References
Problem
Three issues in
crates/storage/src/store.rs:1. ORDER BY violates DAG ordering (CRITICAL)
history()usesORDER BY timestamp_hint_ms DESC, seq DESC(line 120).sync_since()usesORDER BY seq ASC(line 164). Neither respects the DAG's topological order. Peers syncing from storage may receive events in wrong order, causingInsertError::SeqGapor state corruption.The spec requires events to be returned in topological order (causal parents before dependents).
2. No disk size limit (CRITICAL)
Events are inserted indefinitely with no eviction or size limit. A storage node can fill the entire disk and crash with no graceful degradation.
3. Corrupt events silently skipped (CRITICAL)
All deserialization uses
.ok()filter:Corrupted events are silently dropped — no logging, no alerting. Query returns fewer events than expected with no indication of data loss.
Impact
Suggested fix
EventDag::topological_sort()order, or store a topo-sort index--max-eventsor--max-size-gbconfig with oldest-event evictionLocation
crates/storage/src/store.rs:120,164-165,206-207(ordering)crates/storage/src/store.rsentire (disk limit)crates/storage/src/store.rs:143,175,224(deserialization)References