Skip to content

backport: assumeutxo M4 — evo snapshot format v3 and LLMQ reconstruction#53

Open
PastaPastaPasta wants to merge 4 commits into
assumeutxo/m3-background-completionfrom
assumeutxo/m4-evo-snapshot
Open

backport: assumeutxo M4 — evo snapshot format v3 and LLMQ reconstruction#53
PastaPastaPasta wants to merge 4 commits into
assumeutxo/m3-background-completionfrom
assumeutxo/m4-evo-snapshot

Conversation

@PastaPastaPasta

@PastaPastaPasta PastaPastaPasta commented Jul 12, 2026

Copy link
Copy Markdown
Owner

Issue being fixed or feature implemented

Upstream UTXO-only snapshots can't validate a DIP3-active chain like Dash's:
masternode lists, LLMQ quorums/rotation, the credit pool, and EHF state all
need to be captured and reconstructible from a snapshot, independently
verifiable against the chain (not merely trusted). This is milestone 4/7, the
largest design unit of the series (10 review rounds; design docs D1/D2). The
execution plan and per-unit ledger (M4 section) are tracked outside the repo
in a private gist, not checked in: https://gist.github.com/PastaPastaPasta/aa52b1f89fb74a0566ba3b5e15afab6a
loadtxoutset is deliberately still unexposed after this PR — it needs the
format landed here, but the RPC itself arrives in M5.

PR 4/7 in the stacked series — base is M3 (assumeutxo/m3-background-completion).

This PR implements the user-locked design decision (2026-07-11): the evo
snapshot carries the FULL quorum member-reconstruction history, diff-encoded
from the base MN list, plus per-work-block score modifiers/CbTx signatures —
chosen over a smaller verification-only format because both rotated and
non-rotated GetHashModifier need CbTx data unavailable pre-completion, and
reconstructing the active non-rotated set needs MN lists ~24 cycles (~576
blocks) to ~2,304 blocks back, depending on quorum type.

What was done?

  • B4.1 — evo snapshot format v3 + evo_hash: CEvoSnapshot v3 replaces
    full historical lists with one canonical reverse diff chain from the base
    list through every required LLMQ work block (predecessor/target hashes,
    height, registration counter, canonical target hash, bounded canonical
    CDeterministicMNListDiff per link; exact (llmq_type, work_block_hash, modifier) tuples for every commitment/rotation reference). A pure horizon
    enumerator covers non-rotated active+safety cycles and rotated H-C..H-4C
    (worst default span 2,312 blocks; 104 on regtest), with a params-derived
    link count cap (192 max with currently enabled LLMQs) and a shared
    786,432-operation decode budget. Five review rounds.
  • B4.2 — dump emission + populate/seed v3: dumptxoutset builds the v3
    section under the coins-cursor cs_main pin; populate validates ancestry,
    exact history/modifier coverage, work-block relationships, evo_hash, and
    CbTx roots, then atomically seeds reconstructed lists, modifiers,
    commitments, rotation snapshots, credit pool, and MNHF state under the
    snapshot EvoDB identity. A modifier-mismatch signal is contained at quorum,
    connect/disconnect, direct-validity, VerifyDB, and replay boundaries and
    routes to the controlled invalid-snapshot/shutdown path. 3 review rounds.
  • B6 — init-order integration: reindex modes remove all snapshot
    lifecycle dirs before the EvoDB wipe/detection; an assumeutxo prune lock
    protects the base block until deferred CbTx/evo checks complete. Round 2
    review found a released prune lock resurrected by DisconnectTip rewind —
    fixed via BlockManager::DeletePruneLock.
  • Circular-deps refactor: 6 new cycles introduced by the M4 work were
    broken by extracting evo/snapshot_types.h and moving snapshot
    load/seed/completion orchestration into evo/snapshot_load.cpp (note for
    future backports: upstream hunks touching PopulateAndValidateSnapshot /
    MaybeCompleteSnapshotValidation in validation.cpp must be retargeted
    there).
  • Tests prove diff determinism, cumulative bounded decode, exact modifier
    cross-checking, and rotated/non-rotated GetAllQuorumMembers
    reconstruction with block data unavailable, using an independent manager
    oracle; removing a seed trips the fail-closed NORMAL-state barrier
    (also covers ScanQuorums and recovered-signature verification).

How Has This Been Tested?

  • make check: exit 0, 0 failures (rerun on the final post-refactor tree).
  • Functional battery (12): feature_assumeutxo_dash, feature_dip3 ×2,
    feature_llmq_signing ×2, feature_llmq_rotation,
    feature_llmq_chainlocks, feature_mnehf, feature_asset_locks,
    feature_init, feature_reindex, feature_pruning — all passed.
  • Lint: circular-dependencies PASS, whitespace PASS; python lint deferred to CI.
  • Milestone gate PASS on 2026-07-11.

Breaking Changes

Snapshot format is new/versioned (v3) and unreleased; no compatibility
surface exists yet. loadtxoutset remains unexposed to end users until M5.

Checklist:

  • I have performed a self-review of my own code
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation (docs rewrite lands in M7/B8)
  • I have assigned this pull request to a milestone

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f11ea72d-01b4-419f-ba35-854fbc55c659

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch assumeutxo/m4-evo-snapshot

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@PastaPastaPasta PastaPastaPasta force-pushed the assumeutxo/m4-evo-snapshot branch from ed610de to 609b604 Compare July 12, 2026 16:01
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