Skip to content

dgb: wire subsidy_func into embedded work source coinbasevalue (Phase B) - #207

Merged
frstrtr merged 1 commit into
masterfrom
dgb/embedded-coinbase-wiring
Jun 19, 2026
Merged

dgb: wire subsidy_func into embedded work source coinbasevalue (Phase B)#207
frstrtr merged 1 commit into
masterfrom
dgb/embedded-coinbase-wiring

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 19, 2026

Copy link
Copy Markdown
Owner

Phase B — first production caller of CoinParams::subsidy_func

DGBWorkSource now carries core::SubsidyFunc and exposes coinbase_value(height, total_fees, gbt_coinbasevalue), routing through dgb::coin::resolve_coinbase_value (the #188 SSOT in embedded_coinbase_value.hpp). Until now subsidy_func was oracle-conformed in params.hpp but had zero production invocation sites — the live path only ever read coinbasevalue off external GBT. This is the wiring the SSOT comment and test_dgb_coinbase_value pointed at (Stage 4c, work_source.cpp).

  • main_dgb.cpp passes params.subsidy_func at DGBWorkSource construction.
  • External-daemon GBT fallback PERSISTS: a present GBT coinbasevalue is returned verbatim; only the embedded (no-RPC) path derives subsidy_func(height)+fees locally.
  • Consensus-bearing (coinbase value path) — behaviorally a no-op given the oracle-verified subsidy(); the boundary test is what proves that.

Tests (3 added to existing dgb_work_source_test — no new target, #143 trap avoided)

  • embedded derivation == p2pool-dgb-scrypt oracle subsidy at all four reward-era boundaries (zero fees)
  • additive fees on embedded path
  • GBT coinbasevalue honored verbatim (fallback precedence)

13/13 PASS, c2pool-dgb links clean. Fenced to src/impl/dgb/ + DGB-only main_dgb.cpp; no shared base / web_server / bitcoin_family / other coin tree.

Advances the embedded-P2P arm of #82 (won-block-reaches-network) toward a faithful embedded template; #82 stays open.

DGBWorkSource now carries CoinParams::subsidy_func and derives the embedded
template coinbasevalue through dgb::coin::resolve_coinbase_value (the #188
SSOT) — the first PRODUCTION invocation site of subsidy_func, which until now
had only test callers. main_dgb.cpp passes params.subsidy_func at construction.

External-daemon GBT coinbasevalue is returned verbatim when present (the
fallback that MUST PERSIST); the embedded path derives subsidy_func(height) +
fees from the DGB oracle decay schedule. Three tests added to the existing
dgb_work_source_test (no new target, #143 allowlist trap avoided): embedded
derivation at all four reward-era boundaries vs the p2pool-dgb-scrypt oracle,
additive fees, and GBT-verbatim precedence. 13/13 PASS.
@frstrtr
frstrtr merged commit d283596 into master Jun 19, 2026
18 checks passed
frstrtr added a commit that referenced this pull request Jun 19, 2026
…209)

Add tip_height()/next_block_height()/base_height()/set_base_height() to
dgb::HeaderChain. Block height is a pure function of base height + appended
header count: index i holds absolute height base+i, no separate counter that
could drift from m_chain.

DGB counts every block of every algo as one height, so height advances on
BOTH VALIDATED_SCRYPT and ACCEPTED_CONTINUITY ingests and only those -- a
REJECTED header is checked before push_back and never advances. set_base_height
seeds a fast-start checkpoint while the chain is empty (default 0 = genesis).

This is the next_h source the embedded TemplateBuilder port needs for the
BIP34 height push and the subsidy_func(height) lookup that feeds the embedded
coinbasevalue SSOT (#207); external-daemon GBT keeps its own authoritative
height field. Fenced to src/impl/dgb/. +4 tests into header_chain_test
(no new gtest target), 31/31 pass.

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jun 19, 2026
Wire the build_work_template SSOT (Stage 4c, #219) into the embedded work
path so it has a REAL second caller. Until now build_work_template had a
single caller (DGBWorkSource::get_current_work_template), leaving its "the
embedded path and the stratum path cannot emit a divergent template" claim
theoretical; the embedded path being the second caller proves it.

New coin/embedded_coin_node.hpp: EmbeddedCoinNode implements the existing
CoinNodeInterface::getwork() (coin/template_builder.hpp) by assembling a
GBT-compatible template ENTIRELY from in-process embedded chain state -- the
HeaderChain (next_block_height / median_time_past / tip_hash) plus the coin
subsidy schedule -- with NO external RPC. make_inputs(curtime) is split out
so the assembly is deterministically testable; getwork() supplies
std::time(nullptr) exactly as the stratum caller does.

Consensus discipline identical to the stratum caller (pure non-consensus
shaping):
  - coinbasevalue resolved through the #207 resolve_coinbase_value ->
    subsidy_func SSOT. Embedded path has no external GBT figure, so it is
    derived as subsidy_func(height)+total_fees (total_fees 0 until embedded
    mempool tx selection is wired). The external-daemon GBT fallback
    (NodeRPC::getwork) is a SEPARATE path and stays untouched.
  - version pins the Scrypt lane; transactions[] empty (no fabrication);
    previousblockhash emitted ONLY when tip_hash() carries a real id;
    bits HELD BACK (MultiShield V4 next-target == V37).

New coin/hash_format.hpp lifts u256_be_display_hex out of work_source.cpp
into a dgb::coin SSOT so the stratum and embedded callers render
previousblockhash in one byte-encoding -- the same anti-divergence intent.
work_source.cpp now consumes it via a using-declaration; behaviour
preserved (dgb_work_source_test 17/17 unchanged, dgb_template_builder_test
7/7 unchanged).

New dgb_embedded_coin_node_test 5/5: SSOT routing (node == build_work_template
for the same inputs), coinbasevalue via subsidy_func, prevhash truthful
absence + byte-identical emit, getwork no-fabrication. Wired into ctest +
both build.yml --target allowlists (#143 NOT_BUILT trap avoided). Fenced to
src/impl/dgb only; build EXIT=0.
frstrtr added a commit that referenced this pull request Jun 20, 2026
… (surface-for-tap, consensus VALUE) (#248)

* dgb: wire embedded mempool tx selection into the work template (fees -> coinbasevalue, transactions[])

EmbeddedCoinNode gains an injected EmbeddedTxSource: the embedded work
template's transactions[] and fee total now come from the in-process
Mempool instead of being hardcoded empty/0. The fee total folds into
coinbasevalue through the #207 resolve_coinbase_value SSOT (subsidy(h)
+ total_fees); transactions[] passes through build_work_template
verbatim. The source defaults empty, so the #237 EmbeddedCoinNode call
site stays byte-identical (truthful absence preserved).

The heavy tx/UTXO serialization codec (TX_WITH_WITNESS pack + Hash +
HexStr) lives out-of-line in embedded_tx_select.cpp (make_mempool_tx_source,
compiled into dgb_coin), NOT in embedded_coin_node.hpp -- keeping that
header codec-free holds the #143 btclibs SCC trap shut for guard-weight
TUs. Per-tx entry shape {data,txid,hash,fee} mirrors btc/coin and the
p2pool-dgb-scrypt GBT consumer (fee null when unknown -> base_subsidy
fallback; unknown-fee txs excluded to avoid coinbasevalue desync).

Tests: dgb_embedded_tx_select_test (3/3) pins the Mempool -> GBT shaping
+ fee total over a real pool; dgb_embedded_coin_node_test (+2 -> 7/7)
pins the fee->coinbasevalue fold (#207) and the empty-source
byte-identical invariant. Both registered in ctest + the two build.yml
--target allowlists.

* dgb: inject make_mempool_tx_source into embedded run-loop work source

Wire the #244 EmbeddedTxSource seam into the c2pool-dgb run loop. The
EmbeddedCoinNode ctor now receives make_mempool_tx_source(mempool,
BLOCK_MAX_WEIGHT): the served work template selects fee-sorted mempool
transactions and folds their fees into coinbasevalue via the #207 SSOT,
instead of emitting subsidy-only with an empty transactions[].

mempool is hoisted ahead of embedded_coin so the injected source (which
captures it by reference) is outlived by the pool; reverse-order
destruction tears the source down before the pool. The duplicate lower
mempool declaration is removed.

Consensus-VALUE: this changes the served template tx-selection path, so
it is surface-for-tap, not auto-merge. It is byte-identical to the #237
subsidy-only baseline until the mempool is fed: wire_mempool_ingest
(#245) needs an embedded coin-daemon ::dgb::interfaces::Node new_tx
relay, and no such node is constructed in the run loop yet (the M3
embedded port; header_chain is likewise still unfed). So the source
returns an empty selection today and the broadcast template is unchanged
until live tx ingest lands.

Build: c2pool-dgb links EXIT=0; --selftest OK.

---------

Co-authored-by: frstrtr <frstrtr@users.noreply.github.com>
frstrtr added a commit that referenced this pull request Jun 23, 2026
…mpool

Wire DGBWorkSource::get_current_work_template to select fee-sorted mempool
transactions via the make_mempool_tx_source SSOT (BLOCK_MAX_WEIGHT cap),
mirroring the embedded node path (#248). The selection shapes GBT
transactions[] and its fee total folds into coinbasevalue through the #207
resolve_coinbase_value SSOT; the builder passes the array through verbatim.

On the current empty embedded mempool the call yields an empty transactions[]
and total_fees=0 -- byte-identical to the prior coinbase-only template. It
lights up unchanged once the embedded P2P mempool feed populates the pool.
DGB-tree only; shared modules untouched. dgb_share_test 26/26, block_assembly
8/8, mempool_ingest 5/5; c2pool-dgb links.
frstrtr added a commit that referenced this pull request Jul 3, 2026
Wire DGBWorkSource::set_external_gbt_fn in main_dgb.cpp so that when
--coin-rpc arms the NodeRPC, the daemon getblocktemplate becomes the
authoritative stratum work template via select_work_template() (#207
SSOT coinbasevalue reconcile). Serves the daemon transactions[] -> the
stratum now emits POPULATED-block work, not coinbase-only. Unbound (no
--coin-rpc) stays byte-identical to the pre-wire embedded path; the
submit_block_hex RPC fallback is untouched.
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