Skip to content

dgb: template-txs producer bridge (tx-inclusion slice — decode GBT transactions[] into won-block other_txs) - #299

Merged
frstrtr merged 1 commit into
masterfrom
dgb/tx-inclusion-template-bridge
Jun 21, 2026
Merged

dgb: template-txs producer bridge (tx-inclusion slice — decode GBT transactions[] into won-block other_txs)#299
frstrtr merged 1 commit into
masterfrom
dgb/tx-inclusion-template-bridge

Conversation

@frstrtr

@frstrtr frstrtr commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Producer half of the DGB tx-inclusion slice (integrator greenlit, own branch off master, fenced to src/impl/dgb/).

The gap

The won-block reconstructor make_reconstruct_closure_from_template frames the broadcast block as [gentx] ++ other_txs. make_mempool_tx_source already shapes the GBT template transactions[] ({data,txid,hash,fee}). Nothing yet decodes that template back into the std::vector the reconstructor consumes — this adds that wire.

What lands

  • coin/template_other_txs.hpp (new, fenced):
    • deserialize_template_other_txs(json) — pure transactions[] -> txs[] SSOT; throws on malformed data (bad hex / trailing bytes) so the closure fails the won block CLOSED, never broadcasts a half-decoded set (mirrors unpack_gentx_coinbase).
    • make_template_other_txs_fn(captured_template_txs_fn) — adapts a per-share captured-transactions[] provider into the run-loop template_other_txs_fn. The provider must return the template the won share was mined against (per-job capture seam, dgb(#82): reconstruct won block from captured GBT template, not share refs #271), not the live mempool — that capture provider is the run-loop integration, not this slice.
  • test/template_other_txs_test.cpp (dgb_template_other_txs_test, 5/5): round-trips the PRODUCTION make_mempool_tx_source output byte-faithfully (re-serialize == data, txid match, template order), proves funded template txs land in the reconstructed block byte-identical to reconstruct_won_block_from_template, and proves a bad provider fails closed.

Conformance / isolation

No p2pool-merged-v36 surface — decodes the conformant GBT shape back into the in-memory tx. Per-coin isolation held (src/impl/dgb/ only). Both build.yml allowlists updated (#143 NOT_BUILT trap).

Non-blocking for the #82 broadcaster gate (already closed). Live tx-bearing dual-arm regtest re-run rides on this bridge and is the follow-up.

…e won-block reconstructor other_txs

The won-block reconstructor (make_reconstruct_closure_from_template) frames the
broadcast block as [gentx] ++ other_txs, where other_txs is the captured GBT
template's non-coinbase set. make_mempool_tx_source already shapes that template
(transactions[] of {data,txid,hash,fee}); the reconstructor consumes deserialized
MutableTransaction. This adds the missing deserialize wire between them:

  * deserialize_template_other_txs(json) -- pure transactions[] -> txs[] SSOT;
    throws on malformed data (bad hex/trailing bytes) so the closure fails the
    won block CLOSED rather than broadcasting a half-decoded tx set.
  * make_template_other_txs_fn(captured_template_txs_fn) -- adapts a per-share
    captured-transactions[] provider into the template_other_txs_fn the run-loop
    installs (per-job capture provider is the run-loop integration, #271).

dgb_template_other_txs_test (5/5): round-trips the PRODUCTION make_mempool_tx_source
output byte-faithfully, proves the funded template txs land in the reconstructed
block ([gentx]++other_txs byte-identical to reconstruct_won_block_from_template),
and proves a bad provider fails closed. Fenced to src/impl/dgb/; no p2pool-merged-v36
surface (decodes the conformant GBT shape back into the in-memory tx). Both
build.yml allowlists updated (#143 NOT_BUILT trap).
@frstrtr
frstrtr merged commit 8a79990 into master Jun 21, 2026
29 checks passed
frstrtr added a commit that referenced this pull request Jun 21, 2026
…der (#271)

The won-block reconstructor frames the broadcast block as [gentx] ++ other_txs,
where other_txs is the captured-GBT template the won share was mined against. The
into that seam but defers the provider itself to the run-loop. main_dgb installs an
interim mempool RE-SELECTION lambda, merkle-consistent ONLY while the mempool is
static across the won window (regtest); in prod any mempool mutation between job
hand-out and won-block diverges the set -> wrong merkle root -> daemon-rejected
block -> lost reward.

coin/template_capture.hpp removes that race: TemplateCapture retains each handed-out
template transactions[] keyed by the resulting share_hash and replays it verbatim at
won-block. provider() yields the captured_template_txs_fn make_template_other_txs_fn
consumes. Miss -> empty array -> a VALID coinbase-only block (the reconstructor empty
contract), NOT fail-closed: a missing template must not forfeit the subsidy. Bounded
FIFO so memory is O(capacity), not O(jobs). Thread-safe (capture on the job/mint path,
provide on the COMPUTE thread inside the closure).

dgb_template_capture_test (5/5): capture->provide json round-trip; miss replays empty;
composed through the #299 bridge a HIT decodes byte-faithfully to the MutableTransaction
vector deserialize_template_other_txs yields directly and a MISS to empty; overwrite-
same-hash keeps one entry; FIFO eviction drops the oldest. Stacks on #299. Fenced to
src/impl/dgb/; no p2pool-merged-v36 surface. Both build.yml allowlists updated (#143).
frstrtr added a commit that referenced this pull request Jun 23, 2026
dgb: template-txs producer bridge (tx-inclusion slice — decode GBT transactions[] into won-block other_txs)
frstrtr added a commit that referenced this pull request Jun 23, 2026
…der (#271)

The won-block reconstructor frames the broadcast block as [gentx] ++ other_txs,
where other_txs is the captured-GBT template the won share was mined against. The
into that seam but defers the provider itself to the run-loop. main_dgb installs an
interim mempool RE-SELECTION lambda, merkle-consistent ONLY while the mempool is
static across the won window (regtest); in prod any mempool mutation between job
hand-out and won-block diverges the set -> wrong merkle root -> daemon-rejected
block -> lost reward.

coin/template_capture.hpp removes that race: TemplateCapture retains each handed-out
template transactions[] keyed by the resulting share_hash and replays it verbatim at
won-block. provider() yields the captured_template_txs_fn make_template_other_txs_fn
consumes. Miss -> empty array -> a VALID coinbase-only block (the reconstructor empty
contract), NOT fail-closed: a missing template must not forfeit the subsidy. Bounded
FIFO so memory is O(capacity), not O(jobs). Thread-safe (capture on the job/mint path,
provide on the COMPUTE thread inside the closure).

dgb_template_capture_test (5/5): capture->provide json round-trip; miss replays empty;
composed through the #299 bridge a HIT decodes byte-faithfully to the MutableTransaction
vector deserialize_template_other_txs yields directly and a MISS to empty; overwrite-
same-hash keeps one entry; FIFO eviction drops the oldest. Stacks on #299. Fenced to
src/impl/dgb/; no p2pool-merged-v36 surface. Both build.yml allowlists updated (#143).
frstrtr added a commit that referenced this pull request Jun 23, 2026
Replace the interim coinbase-only template_other_txs_fn stub in the #82
forced-won live seam with the production capture->bridge path:

- declare a run-loop-scoped dgb::coin::TemplateCapture (#300/#271) that
  outlives every tracker callback the provider() is installed into
- feed it through make_template_other_txs_fn (#299) as the reconstruct
  closure template_other_txs_fn, so a won block replays the EXACT
  non-coinbase set the share committed to (merkle-consistent) instead of
  reconstructing coinbase-only
- seed_forced_from_gbt captures the node-B GBT transactions[] keyed by the
  forced share hash; coinbasevalue already includes those fees so the
  regenerated gentx subsidy stays balanced

A capture MISS still decodes to an empty set -> a valid coinbase-only
block (never fail-closed). Per-coin: src/impl/dgb + main_dgb only.
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