Skip to content

fix(rust_brain): preserve HLC on snapshot restore and gossip receive#24

Draft
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-investigation-fbfb
Draft

fix(rust_brain): preserve HLC on snapshot restore and gossip receive#24
cursor[bot] wants to merge 1 commit into
mainfrom
cursor/critical-bug-investigation-fbfb

Conversation

@cursor

@cursor cursor Bot commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

Bug and impact

Critical data-loss bug in disaster recovery and distributed sync.

restore_from_file() dropped Hybrid Logical Clock (HLC) timestamps added in v0.6.0. After a snapshot restore, nodes received fresh HLCs instead of their original causal timestamps. Any post-crash replication, gossip replay, or bulk write carrying pre-crash HLC values was rejected by monotonic enforcement — silent data loss.

Separately, gossip.receive() ignored HLC entirely: stale gossip events without timestamps could overwrite fresher local data.

Concrete trigger: Node A writes key=foo with hlc=(5000, 10, "nodeA"), snapshots, crashes, restores. Peer B replays the write with the original HLC → TimestampRegression → write dropped.

Root cause

v0.6.0 added HLC to MemoryNode and monotonic enforcement in remember(), but restore_from_file() and gossip.receive() were not updated to preserve/apply HLC fields.

Fix

  • Add _parse_hlc() for snapshot/wire normalisation with legacy fallback for pre-v0.6.0 snapshots
  • restore_from_file: restore hlc per node and advance global _hlc
  • bulk_write: pass through hlc from row payloads
  • gossip.receive: apply hlc, reject stale updates, skip missing-hlc overwrites on existing keys

Validation

  • New tests: snapshot HLC round-trip, gossip stale/new/missing-hlc cases
  • Full suite: 192 passed, 8 skipped
Open in Web View Automation 

restore_from_file dropped hlc fields added in v0.6.0, assigning fresh
timestamps on restore. Post-crash causal writes and gossip replays with
pre-crash HLC were rejected (silent data loss), while gossip events
without HLC could overwrite fresher data.

- Add _parse_hlc() for snapshot/wire normalisation with legacy fallback
- restore_from_file: restore hlc and advance global _hlc per node
- bulk_write: pass through hlc from row payloads
- gossip.receive: apply hlc, reject stale updates, skip missing-hlc
  overwrites on existing keys
- Tests: snapshot HLC round-trip, gossip stale/new/missing-hlc cases

Co-authored-by: Daniel <DJLougen@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant