Skip to content

Commit a77ccb9

Browse files
committed
bch(m5): EmbeddedDaemon entrypoint assembly — own+wire coin::Node/EmbeddedCoinNode/AblaRuntime
One owner per embedded daemon instance: constructs HeaderChain, Mempool, EmbeddedCoinNode, coin::Node<Config> and AblaRuntime in lifetime order, runs the node, and closes the ABLA size loop via AblaRuntime::wire(). Embedded getwork() is the primary work source; the external BCHN-RPC fallback path (coin::Node::init_rpc/m_rpc) is retained alongside per the per-coin external_fallback invariant. Cold-start floor-anchored ABLA; the VM300 BCHN-pin reanchor is exposed as apply_bchn_anchor() and left for the operator-gated anchor-capture step. Header-only, build-inert, src/impl/bch only, zero p2pool-merged-v36 surface.
1 parent e464cff commit a77ccb9

1 file changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#pragma once
2+
// ---------------------------------------------------------------------------
3+
// bch::coin::EmbeddedDaemon<Config> -- M5: the embedded-daemon ENTRYPOINT
4+
// assembly. After AblaRuntime (9f5050f2) closed the size loop, four front-ends
5+
// existed but nothing OWNED them as one running daemon instance:
6+
// HeaderChain -- SPV header store + tip (M3); height source
7+
// Mempool -- tx acceptance pool (M4); template input
8+
// EmbeddedCoinNode -- in-process getwork() work source (template builder)
9+
// coin::Node<Config> -- P2P + external-RPC front-end; the full_block source
10+
// (derives bch::interfaces::Node) AND the retained
11+
// external BCHN-RPC fallback path (init_rpc / m_rpc)
12+
// AblaRuntime -- owns AblaTracker + AblaBlockFeed; wires full_block
13+
// --> feed --> tracker --> EmbeddedCoinNode budget
14+
//
15+
// This object is that owner: one daemon = one EmbeddedDaemon. It constructs the
16+
// members in the lifetime order the wiring demands, runs the node, and closes
17+
// the ABLA loop via AblaRuntime::wire(). It is the site coin::Node<Config>
18+
// instantiates concretely (config binds here, per node.hpp's deferral note).
19+
//
20+
// EMBEDDED-PRIMARY, EXTERNAL-FALLBACK (v36-master-plan, REQUIRED for every coin)
21+
// The embedded work source (EmbeddedCoinNode::getwork) is the DEFAULT. The
22+
// external BCHN-RPC path stays alongside it -- coin::Node::init_rpc() is NOT
23+
// removed; m_node keeps its NodeRPC. The CoinNode seam (node_iface.hpp) is
24+
// built embedded-primary with the RPC as the live fallback. Removing the
25+
// external path would violate the per-coin external_fallback invariant.
26+
//
27+
// COLD START = FLOOR ANCHOR (VM300 pin is the NEXT, operator-gated step).
28+
// Absent a BCHN-pinned {height,State} captured from VM300 bchn-bch, the ABLA
29+
// runtime anchors at the activation/floor State -- folding live block sizes
30+
// forward can only RAISE the budget, never undercut the 32 MB floor. The
31+
// BCHN pin is a later reanchor() passthrough (AblaRuntime::reanchor), NOT a
32+
// reconstruction; capturing it touches VM300 read-only and is surfaced to the
33+
// operator as a [decision-needed] before any read. This assembly is complete
34+
// and correct WITHOUT the pin; the pin only sharpens the cold-start budget.
35+
//
36+
// LIFETIME (members declared in this exact order so refs bind to live objects):
37+
// m_chain before m_embedded (EmbeddedCoinNode HeaderChain&) and m_abla
38+
// (AblaBlockFeed HeaderChain&) -- both bind to a constructed chain.
39+
// m_pool before m_embedded (EmbeddedCoinNode Mempool&).
40+
// m_embedded, m_node before wire() hands their addresses to m_abla; m_abla's
41+
// AblaTracker outlives the EmbeddedCoinNode raw pointer it sinks into
42+
// (the daemon owns all of them for its whole run).
43+
//
44+
// p2pool-merged-v36 SURFACE: NONE. Pure local daemon assembly -- no PoW hash,
45+
// share format, coinbase commitment, AuxPoW, or PPLNS math is touched; getwork
46+
// emits the same coin-agnostic WorkData the sweep already pinned conformant.
47+
// PER-COIN ISOLATION: src/impl/bch/coin/ only; every type is bch-owned.
48+
// Build-INERT / source-only: header-only, no impl_bch CMake registration
49+
// (bch stays skip-green; don't race ci-steward).
50+
// ---------------------------------------------------------------------------
51+
52+
#include <cstdint>
53+
54+
#include "header_chain.hpp" // HeaderChain
55+
#include "mempool.hpp" // Mempool
56+
#include "template_builder.hpp" // EmbeddedCoinNode
57+
#include "node.hpp" // coin::Node<Config> (interfaces::Node source)
58+
#include "abla_runtime.hpp" // AblaRuntime (owns tracker + feed)
59+
60+
#include <core/log.hpp>
61+
62+
namespace bch {
63+
namespace coin {
64+
65+
/// Owns and wires one embedded BCH daemon instance. Single-threaded
66+
/// construction from the binary entrypoint; run() then drives the node.
67+
template <typename ConfigType>
68+
class EmbeddedDaemon {
69+
public:
70+
using config_t = ConfigType;
71+
72+
/// Cold-start ctor: floor-anchored ABLA at `anchor_height` (safe default
73+
/// when no VM300 BCHN pin is available yet). `context`/`config` outlive the
74+
/// daemon (owned by the binary entrypoint, same contract as coin::Node).
75+
EmbeddedDaemon(auto* context, config_t* config, uint32_t anchor_height)
76+
: m_config(config),
77+
m_chain(),
78+
m_pool(),
79+
m_embedded(m_chain, m_pool, config->m_testnet),
80+
m_node(context, config),
81+
m_abla(config->m_testnet, anchor_height, m_chain) {}
82+
83+
EmbeddedDaemon(const EmbeddedDaemon&) = delete;
84+
EmbeddedDaemon& operator=(const EmbeddedDaemon&) = delete;
85+
86+
/// Bring the daemon up: start the node front-end (external RPC fallback +
87+
/// P2P relay) and close the ABLA size loop. After this, full_block events
88+
/// flow node --> feed --> tracker --> EmbeddedCoinNode dynamic budget, and
89+
/// EmbeddedCoinNode::getwork() is the live in-process work source.
90+
void run() {
91+
m_node.run(); // init_rpc(): external BCHN-RPC fallback retained
92+
m_abla.wire(m_node, m_embedded);
93+
LOG_INFO << "[EMB-BCH] embedded daemon up: embedded-primary work source,"
94+
<< " external BCHN-RPC fallback retained, ABLA loop closed"
95+
<< " (cold-start floor anchor; VM300 pin pending operator).";
96+
}
97+
98+
/// Apply a BCHN-pinned {height, State} captured from VM300 bchn-bch. This
99+
/// is the operator-gated reanchor step -- call ONLY after the read is
100+
/// approved; until then the floor anchor is correct and never-undercut.
101+
void apply_bchn_anchor(uint32_t height, abla::State state) {
102+
m_abla.reanchor(height, state);
103+
}
104+
105+
// Accessors for the CoinNode seam cluster (embedded-primary + RPC fallback)
106+
// and for tests; the daemon retains ownership.
107+
EmbeddedCoinNode& embedded() { return m_embedded; }
108+
Node<config_t>& node() { return m_node; }
109+
AblaRuntime& abla() { return m_abla; }
110+
HeaderChain& chain() { return m_chain; }
111+
Mempool& mempool() { return m_pool; }
112+
bool is_wired() const { return m_abla.is_wired(); }
113+
114+
private:
115+
config_t* m_config; // not owned (binary entrypoint owns it)
116+
HeaderChain m_chain; // before m_embedded + m_abla: their refs bind here
117+
Mempool m_pool; // before m_embedded
118+
EmbeddedCoinNode m_embedded; // in-process work source
119+
Node<config_t> m_node; // P2P + external-RPC fallback; full_block source
120+
AblaRuntime m_abla; // owns tracker + feed; wired in run()
121+
};
122+
123+
} // namespace coin
124+
} // namespace bch

0 commit comments

Comments
 (0)