dash(fees): W5-A fold-backed fee pricing behind a hash_serialized_2 graduation gate - #1237
Draft
frstrtr wants to merge 1 commit into
Draft
dash(fees): W5-A fold-backed fee pricing behind a hash_serialized_2 graduation gate#1237frstrtr wants to merge 1 commit into
frstrtr wants to merge 1 commit into
Conversation
…raduation gate The dominant dashd-only tx class behind the gbt-xcheck tx-merkle mismatches (20/34 across 26 events) is ordinary fee-payers spending coins OLDER than the node's replay horizon: the forward-built UTXOViewCache cannot price them, so compute_fee_locked marks them fee-unknown and the conservative exclusion drops them — embedded serves a strict SUBSET of dashd and the guard swaps. This wires the W3 full-history UTXO fold (replay_utxo_fold.hpp) in as the mempool's THIRD coin source, behind a reward-safety GRADUATION GATE: * replay_utxo_fold.hpp: format v2 adds the 'G' graduation record, written ONLY by a PASSING try_graduate() with the cursor standing exactly on the pinned anchor (h=2,516,758 / dashd gettxoutsetinfo hash_serialized_2); a hash mismatch POISONS the fold (latched refusal, nothing written). Anchor is KAT-injectable via ReplayUtxoFoldOptions. Opt-in prev-hash linkage check makes silently folding across a reorg structurally impossible (adapter always arms it; synthetic-chain KATs unaffected). * fold_fee_source.hpp (new): FoldFeeSource — the trust latch + threading adapter. lookup() answers ONLY while graduated AND live at the tip AND undisarmed; missing/spent/immature-coinbase all answer false. Any feed refusal (gap, prev-mismatch reorg tripwire, gate FAIL, store error) disarms until restart. Lock order Mempool::m_mutex -> FoldFeeSource:: m_mutex; the feed path never calls into Mempool. * mempool.hpp: set_fee_coin_lookup — a slot SEPARATE from the pinned-tx m_external_coin_lookup (that one is the dashd-RPC arm). Consulted only on the UTXOViewCache-miss + in-pool-parent-miss double miss, in compute_fee_locked AND in the selection-time vin resolution (pricing without resolution would be undone by the stale-input guard). Unset => byte-identical behaviour. * main_dash.cpp: --embedded-utxo-fold-fees DBPATH + REQUIRED --embedded-utxo-fold-expect HEX (the operator restates the anchor; a stale/foreign DB cannot graduate on its own say-so). DEFAULT OFF == nothing constructed. Feeds: the W2 --replay-bulk lane (Tee side consumer; genesis start-height sentinel refuses a cold fold above h=1 at STARTUP instead of a GATE FAIL 15 h of download later; tip_exclusion=0) + the live block_connected leg (idempotent acks, tolerated gaps, note_tip). The #1218 gbt-xcheck-txmerkle guard is untouched and stays the referee: serving still refuses on any divergence; this work makes the arm MATCH. KATs (test_dash_fold_fee_source.cpp, rides the test_dash_mempool target): red/green pair — UngraduatedFoldDoesNotPrice (master's exact behaviour with the fold wired and holding the coin) vs GraduatedFoldPricesOldCoinAndSelectsIt (exact fee, selected into the template); spent-in-fold and immature-coinbase exclusion; GateFailPoisonsAndDisarms; TipLagDropsTrust; GraduationRestoreAcrossReopen (wrong restatement => ignored); PrevLinkageRefusesOrphanFold.
Owner
Author
|
vm905 build + KAT evidence (BLS=REAL)
Fold run STARTED on vm905 (the subsequent-soak half; PR does not block on it): Monitor: Sibling: #1238 (W5-B DSTX leg). Both legs are needed to close all 34/34 dashd-only txs; acceptance = 24 h ZERO tx-merkle mismatches with guards armed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
W5-A: fold-backed fee pricing behind a hash_serialized_2 graduation gate
Goal (dashd-cut Tier-2 "W5", leg A): close the DOMINANT dashd-only tx class behind the
gbt-xcheck-txmerklemismatches — 20/34 txs across the 26-event diagnosis are ordinary fee-payers spending coins OLDER than the replay horizon. The forward-builtUTXOViewCachecannot price them,compute_fee_lockedmarks them fee-unknown, the conservative exclusion drops them, embedded serves a strict SUBSET of dashd, and the guard swaps to the dashd arm. This PR wires the W3 full-history UTXO fold (replay_utxo_fold.hpp) in as the mempool's THIRD coin source — behind a reward-safety graduation gate.DARK / flag-gated
--embedded-utxo-fold-fees DBPATH+ required--embedded-utxo-fold-expect HEX(the operator RESTATES the anchor hash — a stale/foreign DB cannot graduate on its own say-so). Default OFF: nothing is constructed,Mempool::m_fee_coin_lookupstays empty, production byte-identical. DASH lane only. No wire/consensus/share-format change.The graduation gate (reward-safety)
A wrong fee VALUE can overstate coinbasevalue = an invalid found block = a lost block — the tx-merkle guard does not cover fee values. So fold answers are arithmetically unreachable from the fee path until ALL of:
ReplayUtxoFold::try_graduate()runs with the cursor standing exactly on the pinned anchor (h=2,516,758) and proveshash_serialized_2byte-equal to dashd'sgettxoutsetinfo(3d14913768a9d492bfa7a42fe9b111cff625b80e35bb4133e1d60cf3991c2319). PASS writes the durable'G'record (format v2); FAIL poisons the fold (latched refusal, nothing written). Restart restores trust ONLY from a recorded pass that also matches the operator restatement.Every failure path reverts to today's fee-unknown exclusion. The #1218 gbt-xcheck-txmerkle guard is untouched and stays the referee — this PR makes the arm MATCH, it never relaxes the guard.
Pieces
replay_utxo_fold.hpp: format v2 +'G'graduation record,try_graduate()/graduation()/ poison latch, KAT-injectable anchor, opt-in prev-hash linkage check (adapter always arms it; pre-existing synthetic-chain KATs byte-identical).fold_fee_source.hpp(new):FoldFeeSource— trust latch + threading adapter (fold core is single-thread by design). Lock orderMempool::m_mutex → FoldFeeSource::m_mutex; the feed path never calls into Mempool — no cycle. Missing / spent / immature-coinbase outpoints all answer false.mempool.hpp:set_fee_coin_lookup— a slot SEPARATE from the pinned-txm_external_coin_lookup(the dashd-RPC arm; routing mempool pricing through it would be an unflagged production change). Consulted only on the view-miss + in-pool-parent-miss double miss, incompute_fee_lockedAND in the selection-time vin resolution (pricing without resolution would be undone by the stale-input guard).main_dash.cpp: flag family; feeds = the W2--replay-bulklane (Tee side consumer; genesis start-height sentinel refuses a cold fold above h=1 at STARTUP instead of a GATE FAIL 15 h of download later;tip_exclusion=0) + the liveblock_connectedleg (idempotent acks, tolerated gaps,note_tip).KATs (
test_dash_fold_fee_source.cpp, rides thetest_dash_mempooltarget)Red/green pair:
UngraduatedFoldDoesNotPrice(master's exact behaviour with the fold wired and holding the coin — the red shape) vsGraduatedFoldPricesOldCoinAndSelectsIt(exact fee, SELECTED into the template). PlusSpentCoinInFoldNotPriced,ImmatureCoinbaseInFoldNotPriced,GateFailPoisonsAndDisarms,TipLagDropsTrust,GraduationRestoreAcrossReopen(wrong restatement ⇒ ignored),PrevLinkageRefusesOrphanFold.What this PR does NOT include
The full genesis→anchor fold run to the live graduation gate (~29-31 GB download, 6-16 h on vm905) is the SUBSEQUENT soak; the PR lands on KATs + mechanism. The DSTX leg (14/34, necessary-but-not-sufficient) is the sibling PR.
Measurement plan (post-merge, canary posture:
--coin-rpckept, guards active)--replay-utxo-hash --replay-utxo-expectexit-0 as independent re-check.--embedded-utxo-fold-feesarmed on the canary — expect the 20/34 fee-unknown class to close; classify residual dashd-only txs (should be ≈pure DSTX).gbt-xcheck-txmerkle-mismatchevents over all tx-carrying templates, guard still armed; quote fallback-TIME share as well as event counts.