Skip to content

fix: add long peer fuzz and richtext diff catchup#1038

Draft
zxch3n wants to merge 8 commits into
mainfrom
codex/long-peer-fuzz-diff-fix
Draft

fix: add long peer fuzz and richtext diff catchup#1038
zxch3n wants to merge 8 commits into
mainfrom
codex/long-peer-fuzz-diff-fix

Conversation

@zxch3n

@zxch3n zxch3n commented Jun 29, 2026

Copy link
Copy Markdown
Member

Summary

  • Add long_peer_fuzz, a deterministic single-thread multi-peer fuzz runner that does not use cargo fuzz.
  • Write failing artifacts with seed/config/history/state snapshots and a minimized replay when possible.
  • Document usage, seed control, artifact layout, and long-run examples in crates/fuzz/README.md.
  • Fix richtext checkout diff so full-history tracking starts from an exact empty tracker and catches up missing text ops before computing checkout diffs.
  • Keep shallow-history richtext tracking on the existing unknown-base path because older ops may be unavailable.

Root cause

The long peer fuzz found a state-only roundtrip mismatch after checkout. One peer state rendered as u32[18283][18265]28[128][3], while importing the state-only export rendered u32[18283][18265]28[128][3]12.

The richtext checkout diff tracker used an anonymous unknown span as the LCA base. In cross-branch checkout, the target can retain old text that the source deleted. Since that anonymous span has no real id/materialized text, the diff can treat text as already represented and omit the insert/delete needed to reach the target state.

Fix

For full-history docs, richtext diff tracking now uses an exact empty tracker and catches up CRDT text ops from the covered version to the oplog version before applying checkout diffs. covered_vv avoids repeating the full catchup when later diffs can extend from already-covered state.

DiffCalculatorTrait::start_tracking now receives ContainerIdx, so richtext can catch up the correct container. Shallow-history tracking still uses the unknown base path.

Validation

  • cargo check -p loro-internal
  • cargo check -p fuzz --bin long_peer_fuzz
  • cargo test -p fuzz --test long_peer_repro state_only_round_trip_with_shallow_deps_does_not_abort -- --nocapture
  • cargo test -p loro state_only_shallow_since_and_updates_till_cover_export_boundaries
  • cargo test -p loro-internal shallow_dep_ensure_vv_for_uses_shallow_baseline
  • cargo test -p loro shallow_snapshot_test
  • cargo run -p fuzz --release --bin long_peer_fuzz -- --seed 20260629 --peers 12 --ops 10000 --sync-barrier-every 5000 --check-every 20000 --no-minimize --artifact-dir long_peer_fuzz_artifacts/tmp-10k-after-catchup
  • cargo run -p fuzz --release --bin long_peer_fuzz -- --seed 20260629 --peers 12 --duration-secs 60 --sync-barrier-every 5000 --check-every 20000 --no-minimize --artifact-dir long_peer_fuzz_artifacts/one-minute-final-diff-fix

Next: run the same long peer fuzz for 8 hours before marking ready.

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