Skip to content

v9.26.4 review remediations: disclose the redeem collateral floor gate, unify the activation-floor helper#420

Closed
gto90 wants to merge 1 commit into
release/v9.26.4from
fix/v9.26.4-review-remediations
Closed

v9.26.4 review remediations: disclose the redeem collateral floor gate, unify the activation-floor helper#420
gto90 wants to merge 1 commit into
release/v9.26.4from
fix/v9.26.4-review-remediations

Conversation

@gto90

@gto90 gto90 commented Jul 2, 2026

Copy link
Copy Markdown
Member

Remediations from a triple-source review of #418, split out into their own PR so they can be reviewed independently. Stacked on release/v9.26.4; the commit previously pushed to #418 directly was reverted there (596bd1f / 73b5779) and is carried here as 117278c.

What this changes

1. Docs: disclose the consensus rule change (major).
The release notes, both explainers, and the pruning plan claimed "zero consensus changes", but ValidateCollateralReleaseAmount gains two new unconditional gates that run on every node: input 0 below the activation floor is rejected (bad-collateral-release-not-vault), and pre-floor DD-lookalike fee inputs skip the structural collateral check. A v9.26.3 and a v9.26.4 full node can reach different verdicts on a crafted pre-floor coin, and V9.26.4_MAINNET_VALIDATION.md / V9.26.4_TESTNET_PRUNE_SUMMARY.md already call it a consensus fix. The gate itself is correct (it is what keeps pruned and full nodes in agreement); the operator-facing claim was not. All four docs now disclose it as one narrowly scoped consensus rule, with the mainnet scan result referenced.

2. One source of truth for the activation floor (major).
The dd_floor formula was hand-duplicated in four production translation units (validation, chainstate prune lock, health scan seed, oracle startup reconstruction) plus two more mirrored copies inside the new fuzz target, which itself warns the copies must be kept in sync by hand. A drifted copy would silently reintroduce the pruned-vs-full divergence this release exists to close. Added DigiDollar::EarliestActivationFloor(const Consensus::Params&) in src/consensus/digidollar.{h,cpp} and pointed all four sites at it; the fuzz targets now exercise the real helper via a constructed Consensus::Params instead of models.

Behavioral note: the helper returns 0 for NEVER_ACTIVE deployments (as the three startup copies already did); validation's copy previously returned min(nDDActivationHeight, min_activation_height) there. Unreachable on any configured network — main/testnet/regtest all set real start/timeout values, and DigiDollar validation never runs when the deployment can never activate.

3. ScanUTXOSet API safety (minor).
The fail-closed contract (return false on unreadable post-floor block data) is gated on a non-null chain, but chain/consensus defaulted to nullptr, so a future caller omitting them would silently revert to the old silent-undercount behavior. The defaults are removed; the one test caller that relied on them now passes explicit nullptrs.

4. Plan-doc accuracy (minor).
V9.26.4_PRUNING_PLAN.md sections 3b/3c promised two unit-test files that were never created. They now carry "As shipped" notes pointing at the actual coverage (the fuzz target and functional phases F6/F9/F10/F14) and stating that the tip-below-floor no-op case has no direct unit test.

Review-bot comments on #418

All six (4 Copilot, 2 CodeQL/code-quality) were validated against the head and found false, stale, or counterproductive as suggested; each thread has a reply with the reasoning and is resolved. No code changes came from them.

Verification

Full build passes locally on macOS arm64 (make exit 0, including test_digibyte and the fuzz binary). Unit suites could not be executed in the review environment (endpoint security kills freshly built DigiByte binaries); CI on this PR is the test run. Suggested local spot-checks: digidollar_txindex_tests, digidollar_validation_tests, digidollar_health_tests, digidollar_redteam_tests.

…on-floor helper

Triple-review remediations for the v9.26.4 pruning PR:

- docs: the release notes, PR/pruning explainers, and pruning plan no longer
  claim "zero consensus changes"; the redeem collateral floor gate
  (bad-collateral-release-not-vault on input 0, pre-floor fee-input
  classification) is disclosed as one narrowly scoped consensus rule that
  applies to every node, with the mainnet scan result referenced.

- consensus: add DigiDollar::EarliestActivationFloor() in consensus/digidollar
  as the single source of truth for the DigiDollar activation floor. Callers:
  validation's EarliestDigiDollarActivationHeight, the "digidollar" prune-lock
  registration in node/chainstate.cpp, the health-scan seed in
  digidollar/health.cpp, and startup oracle price reconstruction in
  oracle/bundle_manager.cpp — previously four hand-duplicated copies of the
  same expression. Behavioral note: the helper returns 0 for NEVER_ACTIVE
  deployments, which the three startup copies already did; validation's copy
  previously returned min(nDDActivationHeight, min_activation_height) there.
  Unreachable on any configured network (main/testnet/regtest all set real
  start/timeout values, and DigiDollar validation never runs when the
  deployment can never activate).

- fuzz: dd_prune_activation_floor and dd_prune_coin_gating now exercise the
  real shared helper via a constructed Consensus::Params instead of
  hand-copied models of the deleted inline expressions.

- health: ScanUTXOSet's mempool/chain/consensus parameters lose their nullptr
  defaults; the pre-floor skip and the fail-closed incomplete-data check are
  gated on a non-null chain, so every caller must now opt in explicitly
  instead of silently reverting to the old silent-undercount behavior.

- plan doc: sections 3b/3c annotated as-shipped (the promised unit-test files
  were not created; coverage lives in the fuzz target and functional phases
  F6/F9/F10/F14, and the tip-below-floor no-op case has no direct unit test).
Copilot AI review requested due to automatic review settings July 2, 2026 20:24
@gto90 gto90 self-assigned this Jul 2, 2026
@gto90 gto90 added the enhancement New feature or request label Jul 2, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refines the v9.26.4 DigiDollar-compatible pruning work by (1) explicitly documenting the previously undisclosed consensus rule impact, (2) consolidating the DigiDollar activation-floor (“dd_floor”) computation into a single shared helper to prevent drift across call sites, and (3) tightening ScanUTXOSet’s API contract to avoid accidental fail-open behavior.

Changes:

  • Document the redeem-collateral activation-floor gate as a narrowly scoped consensus rule in release notes and pruning docs.
  • Introduce DigiDollar::EarliestActivationFloor(const Consensus::Params&) as the single source of truth and update production + fuzz code to use it.
  • Remove defaulted ScanUTXOSet parameters so callers must explicitly opt into/null out mempool/chain/consensus.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
V9.26.4_PRUNING_PLAN.md Updates plan text to disclose the consensus rule and corrects “promised but not shipped” test-file sections.
V9.26.4_PRUNING_EXPLAINER.md Updates pruning explainer to disclose the consensus rule.
V9.26.4_PR_EXPLAINER.md Updates PR explainer to disclose the consensus rule (but still contains a few now-inconsistent “no consensus change” statements).
doc/release-notes/release-notes-9.26.4.md Release notes updated to disclose the activation-floor collateral gating as a consensus rule.
src/consensus/digidollar.h Declares DigiDollar::EarliestActivationFloor and documents its role as shared floor source-of-truth.
src/consensus/digidollar.cpp Implements DigiDollar::EarliestActivationFloor.
src/node/chainstate.cpp Switches prune-lock floor computation to the shared helper.
src/digidollar/validation.cpp Switches validation’s earliest-activation-floor computation to the shared helper.
src/digidollar/health.h Removes default args from SystemHealthMonitor::ScanUTXOSet and documents the rationale.
src/digidollar/health.cpp Uses the shared helper for the activation floor in ScanUTXOSet.
src/oracle/bundle_manager.cpp Uses the shared helper for floor-gated fail-closed startup behavior.
src/test/fuzz/digidollar_prune_blockdb.cpp Updates fuzz targets to exercise the shared helper instead of replicated models.
src/test/digidollar_redteam_tests.cpp Updates a ScanUTXOSet call site for the new signature.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread V9.26.4_PR_EXPLAINER.md
Comment on lines 22 to +26
**What changes if you don't set `prune=`:** nothing. Your node behaves exactly
like v9.26.3.

**What we changed in consensus:** nothing. Zero consensus changes. A pruned node
accepts and rejects exactly the same blocks as a full node. The Groestl algolock
and the DigiDollar activation schedule are untouched.
**What we changed in consensus:** one narrowly scoped rule. Redemption collateral
classification is now gated on the DigiDollar activation floor (a pre-floor coin can
Comment thread V9.26.4_PR_EXPLAINER.md
Comment on lines +25 to +29
**What we changed in consensus:** one narrowly scoped rule. Redemption collateral
classification is now gated on the DigiDollar activation floor (a pre-floor coin can
never be vault collateral), which is what makes a pruned node accept and reject
exactly the same blocks as a full node. The pre-release mainnet scan found no
existing coins the rule affects. The Groestl algolock and the DigiDollar activation
Comment thread V9.26.4_PR_EXPLAINER.md
Comment on lines +83 to +85
- **Consensus, except the redeem collateral floor gate.** Mint/transfer rules,
oracle bundle rules, lock tiers — all byte-identical. The one change is in
redemption collateral classification (the activation-floor gate above).
Comment on lines +16 to +18
**How v9.26.4 does it** (one narrowly scoped consensus rule — the redeem collateral
floor gate that keeps pruned and full nodes in agreement — everything else opt-in
behind `-prune`):
@gto90 gto90 closed this Jul 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants