|
33 | 33 | #include <impl/dgb/coin/embedded_coin_node.hpp> |
34 | 34 | #include <impl/dgb/coin/embedded_tx_select.hpp> // make_mempool_tx_source (EmbeddedTxSource) |
35 | 35 | #include <impl/dgb/coin/won_block_dispatch.hpp> |
| 36 | +#include <impl/dgb/coin/reconstruct_closure.hpp> // make_reconstruct_closure_from_template (#280) |
| 37 | +#include <impl/dgb/coin/won_share_inputs.hpp> // won_share_inputs (#279) |
36 | 38 | #include <impl/dgb/coin/node_interface.hpp> |
37 | 39 | #include <impl/dgb/coin/header_ingest.hpp> |
38 | 40 | #include <impl/dgb/coin/mempool_ingest.hpp> |
@@ -314,14 +316,71 @@ int run_node(const core::CoinParams& params, bool testnet, |
314 | 316 | // supplied (stays null otherwise -> sink no-ops, RPC fallback still fires). |
315 | 317 | std::unique_ptr<dgb::coin::p2p::NodeP2P<dgb::Config>> coin_p2p; |
316 | 318 |
|
317 | | - p2p_node.tracker().m_on_block_found = dgb::coin::make_on_block_found( |
318 | | - /*reconstruct=*/[](const uint256& share_hash) |
319 | | - -> std::optional<std::pair<std::vector<unsigned char>, std::string>> { |
320 | | - std::cout << "[DGB-POOL-BLOCK] won share " << share_hash.GetHex().substr(0, 16) |
321 | | - << " — reconstruct deferred (embedded gentx/known-tx feed " |
322 | | - "pending Phase B); not broadcast this build" << std::endl; |
323 | | - return std::nullopt; |
| 319 | + // ── #82 FAITHFUL won-block reconstruct closure (replaces the interim |
| 320 | + // nullopt stub) ── make_reconstruct_closure_from_template (#280) composes |
| 321 | + // the three version-AGNOSTIC won-block inputs, bound here to the LIVE |
| 322 | + // sharechain tracker: |
| 323 | + // won_share_fields_fn -> share.m_min_header + m_merkle_link (#279, the |
| 324 | + // two inputs a won share carries verbatim) |
| 325 | + // gentx_bytes_fn -> generate_share_transaction(...).GentxCoinbase |
| 326 | + // .bytes (#173 SSOT). v36_active is re-derived |
| 327 | + // from the share's COMPILE-TIME version inside |
| 328 | + // GST (share_check.hpp:943), so passing false is |
| 329 | + // byte-identical to the verify-path invocation |
| 330 | + // (share_check.hpp:1728) -> the regenerated gentx |
| 331 | + // matches the one that passed verification. |
| 332 | + // template_other_txs_fn -> the captured-GBT template's non-coinbase set |
| 333 | + // (#271). EMPTY today: no per-job template- |
| 334 | + // retention seam in the run-loop yet AND the |
| 335 | + // embedded mempool is unfed, so the served |
| 336 | + // template is coinbase-only => the won block's |
| 337 | + // non-coinbase set IS empty. Correct-and-empty (a |
| 338 | + // valid coinbase-only block), NOT fail-closed; it |
| 339 | + // fills with NO change to this seam once retention |
| 340 | + // + tx-selection land. |
| 341 | + // |
| 342 | + // FIRES on the COMPUTE thread already holding the tracker lock |
| 343 | + // (attempt_verify -> m_on_block_found, share_tracker.hpp:537), so the fns |
| 344 | + // read tracker().chain DIRECTLY and must NOT take read_tracker() (would |
| 345 | + // self-deadlock — the corrected consume-seam audit). Fail-closed end to |
| 346 | + // end: any error in a builder fn throws, is caught inside the closure -> |
| 347 | + // std::nullopt (announce + audit; the RPC submitblock fallback still fires). |
| 348 | + auto& reconstruct_tracker = p2p_node.tracker(); |
| 349 | + auto faithful_reconstruct = dgb::coin::make_reconstruct_closure_from_template( |
| 350 | + /*won_share_fields_fn=*/ |
| 351 | + [&reconstruct_tracker](const uint256& h) -> dgb::coin::WonShareInputs { |
| 352 | + dgb::coin::WonShareInputs si{}; |
| 353 | + bool found = false; |
| 354 | + reconstruct_tracker.chain.get_share(h).invoke([&](auto* obj) { |
| 355 | + si = dgb::coin::won_share_inputs(*obj); |
| 356 | + found = true; |
| 357 | + }); |
| 358 | + if (!found) |
| 359 | + throw std::runtime_error("won_share_inputs: share absent from chain"); |
| 360 | + return si; |
| 361 | + }, |
| 362 | + /*gentx_bytes_fn=*/ |
| 363 | + [&reconstruct_tracker, ¶ms](const uint256& h) |
| 364 | + -> std::vector<unsigned char> { |
| 365 | + dgb::coin::GentxCoinbase gc; |
| 366 | + bool found = false; |
| 367 | + reconstruct_tracker.chain.get_share(h).invoke([&](auto* obj) { |
| 368 | + (void)dgb::generate_share_transaction( |
| 369 | + *obj, reconstruct_tracker, params, |
| 370 | + /*dump_diag=*/false, /*v36_active=*/false, &gc); |
| 371 | + found = true; |
| 372 | + }); |
| 373 | + if (!found || gc.bytes.empty()) |
| 374 | + throw std::runtime_error("gentx regen: share absent / empty gentx"); |
| 375 | + return gc.bytes; |
324 | 376 | }, |
| 377 | + /*template_other_txs_fn=*/ |
| 378 | + [](const uint256&) -> std::vector<dgb::coin::MutableTransaction> { |
| 379 | + return {}; // coinbase-only today (see note above) |
| 380 | + }); |
| 381 | + |
| 382 | + p2p_node.tracker().m_on_block_found = dgb::coin::make_on_block_found( |
| 383 | + /*reconstruct=*/std::move(faithful_reconstruct), |
325 | 384 | /*p2p_relay=*/[&ioc, &coin_p2p](const std::vector<unsigned char>& block_bytes) { |
326 | 385 | // #82 PRIMARY arm: relay the won block over the embedded coin-daemon |
327 | 386 | // P2P producer. The sink fires from the compute thread, so post the |
@@ -459,15 +518,18 @@ int run_node(const core::CoinParams& params, bool testnet, |
459 | 518 | << " bytes=" << block_bytes.size() |
460 | 519 | << " — dispatching via submitblock-RPC arm" << std::endl; |
461 | 520 | // The sharechain P2P-relay arm (m_on_block_found -> |
462 | | - // reconstruct_won_block -> broadcast_won_block) is now bound above |
463 | | - // (reconstructor stack #163/#166/#167/#173/#174/#176/#177 landed); |
464 | | - // its faithful reconstruct closure follows with the embedded feed. |
| 521 | + // reconstruct_won_block -> broadcast_won_block) is bound above with |
| 522 | + // the FAITHFUL template-based reconstruct closure (#280, wired here): |
| 523 | + // share fields (#279) + regenerated gentx (#173) + the captured-GBT |
| 524 | + // template's non-coinbase set (#271, empty until the embedded feed |
| 525 | + // lands). That arm reconstructs + broadcasts a won pool block |
| 526 | + // INDEPENDENTLY of this Stratum submitblock fallback. |
465 | 527 | const bool ok = |
466 | 528 | coin_node.submit_block_hex(block_hex, /*ignore_failure=*/false); |
467 | 529 | if (!ok) |
468 | 530 | std::cout << "[DGB-STRATUM-BLOCK] submitblock arm reached NO sink " |
469 | 531 | "(no embedded backend / no digibyted RPC wired yet) " |
470 | | - "— P2P-relay arm pending reconstructor stack" |
| 532 | + "— sharechain P2P-relay arm reconstructs+broadcasts independently" |
471 | 533 | << std::endl; |
472 | 534 | return ok; |
473 | 535 | }; |
|
0 commit comments