dash(oracle): embedded ORACLE-SHADOW validator + graduation gate (first slice) [DRAFT]#793
Draft
frstrtr wants to merge 2 commits into
Draft
dash(oracle): embedded ORACLE-SHADOW validator + graduation gate (first slice) [DRAFT]#793frstrtr wants to merge 2 commits into
frstrtr wants to merge 2 commits into
Conversation
frstrtr
force-pushed
the
dash/embedded-oracle-shadow
branch
from
July 21, 2026 06:29
7dbb8ad to
e0bc3fc
Compare
…duation gate (#793) Cross-checks the daemonless embedded CbTx/block against dashd getblocktemplate{mode:proposal} per tip; regime-aware field-compare diagnosis; persistent coverage ledger + /embedded_oracle GRADUATED verdict. Observe-only, consensus-neutral.
frstrtr
force-pushed
the
dash/embedded-oracle-shadow
branch
from
July 21, 2026 06:32
e0bc3fc to
f371f7d
Compare
…d-side class + folded nits Addresses the PR #793 review (CHANGES-REQUIRED). REQUIRED FIX — false-graduation vector: the NonEmptyTemplate coverage class classified on `!e.empty_template || !d.empty_template`, so DASHD's near-always non-empty template ticked the class while the embedded arm served only empty templates — accruing coverage without ever exercising the embedded tx-selection/ fee-split/special-tx path the class exists to force-sample (where the latent special-tx bug lives). Now classified on the EMBEDDED side only (`!e.empty_template`). Folded review nits: - (a) a dashd-side `rpc-error:` proposal result VOIDs the sample (not REJECTED) — matches propose_block_hex never-throw semantics, no false streak reset. - (b) proposal-mode tip-race reasons (inconclusive/not-best-prevblk/stale) VOID too (bounded settle-resample is a scoped follow-up). is_void_proposal_reason(). - (c) ledger identity: `git describe --tags --always --dirty` so a dirty rebuild cannot inherit a tag-exact clean streak; no-git/dev fallbacks are never-inherit. - (d) creditPool INVARIANT base now comes from the CONNECTED block N-1's committed value (getblock verbosity 2 -> tx[0].cbTx.creditPoolBalance), not dashd's previous TEMPLATE projection — fewer false VIOLs on real asset-lock chains. - (e) the compare (2-3 dashd RPCs + file writes) moved OFF the tip thread onto a dedicated coalescing worker thread; all RPCs run outside the ledger mutex so a hung dashd can neither stall tip processing nor block /embedded_oracle. Worker joined (oracle_shadow.reset) before node_coin_state/rpc unwind. - (f) the 11-KAT test_dash_embedded_oracle_shadow is FOLDED into the already-CI- allowlisted test_dash_embedded_gbt target (no build.yml workflow edit the bot cannot make); 20 tests green. Consensus-neutral: serve/consensus/share path unchanged; the shadow only reads.
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.
Review fixes landed (commit 8ac2ee3)
NonEmptyTemplatenow classifies on the embedded side only (!e.empty_template) — dashd's near-always-non-empty template can no longer tick the class while the embedded arm serves empty templates.rpc-error:+ proposal-mode tip-race reasons (inconclusive/not-best-prevblk/stale) now VOID the sample (no count, no streak reset) instead of false-REJECT.git describe --tags --always --dirty; no-git/dev fallbacks are never-inherit.getblockv2 →tx[0].cbTx.creditPoolBalance), not dashd's previous template projection./embedded_oracle; worker joined beforenode_coin_state/rpcunwind.test_dash_embedded_oracle_shadowis folded into the already-CI-allowlistedtest_dash_embedded_gbttarget (20 tests green) — nobuild.ymlworkflow edit needed.Rebuilt clean; serve path still untouched (consensus-neutral).
Summary
First working slice of the DASH Embedded ORACLE-SHADOW VALIDATOR — the operator's directive toward a fully daemonless c2pool, safely. Run c2pool ALONGSIDE a Dash Core daemon and use dashd as a continuous realtime oracle: on every new tip, verify the daemonless embedded DIP4 CbTx/template arm against what dashd would produce, catching consensus bugs throughout the alpha, plus an objective graduation criterion that says when it is safe to disable the external dashd.
OBSERVE-only / consensus-neutral. The serve/consensus/share path is untouched — the shadow is a separate
new_tipsubscriber that only reads the SAME embedded build path (NodeCoinState::select_work) + the SAME dashd RPC closure the serve arm holds. Empty diff-grep overwork_source.cpp,coinbase_builder.hpp,share_check.hpp,pplns.hpp,node_coin_state.hpp,embedded_gbt.hpp,coin_state_maintainer.hpp.Design doc:
frstrtr/thedocs/c2pool-dash-embedded-oracle-shadow-validator.md(committed). Implements the five §6 conditions ofc2pool-dash-oracle-shadow-adversarial-critique.md.What the first slice does
--embedded-oracle-shadowmode (+--oracle-graduation-blocks N,--oracle-class-coverage K). Arms when the coin-P2P feed is present (--coin-p2p-connect).getblocktemplate{mode:proposal}of the fully-assembled embedded block (NodeRPC::propose_block_hex) —TestBlockValidity, mempool-independent. This is the authoritative pass/fail (the oracle the soaks used, which the naive field-only draft dropped). A served height counts CLEAN only when the proposal is ACCEPTED.getblocktemplate:coinbasevalue − Σfees), MN/quorum roots on empty templates.creditPoolnormalized-base (committed − platformReward − ownΔ == creditPool(N−1)per side) — the exact check that caught the seed bug 3×.[EMB-ORACLE] DIVERGENCE height=<h> class=<c> field=<f> …structured logs + a persistent JSONL ledger under the data-dir./embedded_oracleJSON endpoint:GRADUATED⇔ N consecutive served+proposal-accepted clean blocks AND ≥K served coverage of each class (dkg_window, superblock, post_restart_cold, quorum_rotation, credit_pool_transition, non_empty_template) AND ≥1 reorg AND serve-rate floor AND not-revoked. Selection-bias fix: fall-closed classes are recorded and declared as residual serve-gaps (disabling dashd removes the fallback those classes rely on). Verdict gives the exactstill_needed+residual_serve_gapsbreakdown.(height, prev_hash); ledger hard-keyed to{c2pool_commit, comparator_version, dashd_version, net}(a new binary does not inherit an old streak); revocable by chain-drift sentinels (unknown CbTx version / payload parse fail).Scope of the graduation claim
GRADUATED == chain-state / CbTx-validity equivalence over the served domain (reward-safe daemonless block construction). Soundness rests on the embedded arm's independent chain-state derivation (own SPV/mnlistdiff/quorum/credit-pool pipeline), NOT peer diversity — DASH has no
CoinPeerManager. Full network-standalone daemonless operation additionally needs the separate network-layer gate (independent mempool/relay/propagation/peers); the verdict says so.Build + tests
c2pool-dashbuilds;--selftestpasses;--helpshows the flag.test_dash_embedded_oracle_shadow— 11 hermetic KATs (green) pinning the regime model, the fee-difference-is-not-a-divergence keystone, the creditPool invariant, the bestCL constraint, and the graduation predicate (+ serve-rate floor, fall-closed serve-gap declaration, revocation).Follow-ups (scoped in the design doc)
getdataleg.CoinPeerManagerport to DASH — the network-layer gate.