Skip to content

Commit e464cff

Browse files
committed
bch(m5): AblaRuntime — close embedded-daemon ABLA size loop
Owner that constructs the AblaTracker + AblaBlockFeed and wires them to a live interfaces::Node and EmbeddedCoinNode. The four pieces existed in isolation (tracker folds sizes, feed subscribes to full_block, embedded node consumes the budget, full_block fires post merkle-accept-gate) but nothing tied them together. After wire(): full_block -> AblaBlockFeed -> AblaTracker -> EmbeddedCoinNode::getwork -> TemplateBuilder dynamic ABLA budget (else 32 MB floor). Cold-start floor anchor (never undercuts the 32 MB floor; live sizes only raise it); BCHN-pinned-anchor ctor + reanchor() passthrough for gap/reorg. Tracker declared before feed so lifetimes are correct. Single-coin, src/impl/bch/coin/ only; zero p2pool-merged-v36 surface. Source-only, header-only, no impl_bch CMake registration (bch stays skip-green).
1 parent 19c2b74 commit e464cff

1 file changed

Lines changed: 100 additions & 0 deletions

File tree

src/impl/bch/coin/abla_runtime.hpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#pragma once
2+
// ---------------------------------------------------------------------------
3+
// bch::coin::AblaRuntime -- M5: the CLOSING assembly of the embedded-daemon
4+
// ABLA size loop. The four pieces existed in isolation after slices C/sG:
5+
// AblaTracker -- folds each best-chain block size, holds running State
6+
// AblaBlockFeed -- subscribes to interfaces::Node::full_block, sinks size
7+
// EmbeddedCoinNode -- consumes the tracker for the dynamic build budget
8+
// full_block event -- fires from all 3 p2p delivery paths (direct / cmpct /
9+
// blocktxn) AFTER the merkle-root accept gate (sG)
10+
// ...but nothing OWNED a tracker, owned a feed, and tied them to a live node +
11+
// EmbeddedCoinNode. This runtime is that owner: one object the embedded-daemon
12+
// front-end (coin::Node) holds, constructed once the HeaderChain exists and
13+
// wired once the node + EmbeddedCoinNode exist. After wire():
14+
// full_block --> AblaBlockFeed --> AblaTracker --> EmbeddedCoinNode::getwork
15+
// --> TemplateBuilder dynamic ABLA budget (else 32 MB floor).
16+
//
17+
// COLD START = floor anchor. Absent a BCHN-pinned {height,State}, we anchor at
18+
// the activation/floor State (limit == the 32 MB floor); folding live sizes
19+
// forward can only RAISE the budget, never undercut the floor -- the
20+
// never-undercut invariant holds from the first block. A later BCHN pin is a
21+
// reanchor() passthrough, no reconstruction.
22+
//
23+
// LIFETIME: m_tracker is declared before m_feed so the feed`s AblaTracker&
24+
// binds to a fully-constructed member, and the tracker outlives both the feed
25+
// subscription and the raw pointer handed to EmbeddedCoinNode. The runtime must
26+
// outlive the node it wired (the daemon owns both for its whole run).
27+
//
28+
// p2pool-merged-v36 SURFACE: NONE. Pure local build-time block-size budget --
29+
// no PoW hash, share format, coinbase commitment, or PPLNS math is touched.
30+
// PER-COIN ISOLATION: src/impl/bch/coin/ only; every type reached is bch-owned.
31+
// Build-INERT / source-only: header-only, no impl_bch CMake registration
32+
// (bch stays skip-green; don`t race ci-steward).
33+
// ---------------------------------------------------------------------------
34+
35+
#include "abla.hpp" // abla::State (reanchor / pinned-anchor ctor)
36+
#include "abla_tracker.hpp" // AblaTracker
37+
#include "abla_block_feed.hpp" // AblaBlockFeed
38+
#include "header_chain.hpp" // HeaderChain (height source for the feed)
39+
#include "node_interface.hpp" // bch::interfaces::Node (full_block source)
40+
#include "template_builder.hpp" // EmbeddedCoinNode (set_abla_tracker sink)
41+
42+
#include <core/log.hpp>
43+
44+
#include <cstdint>
45+
46+
namespace bch {
47+
namespace coin {
48+
49+
/// Owns the ABLA tracker + full_block feed for one embedded daemon instance and
50+
/// wires them to a live node + EmbeddedCoinNode. Single-threaded use from the
51+
/// daemon block-processing context (same contract as AblaTracker / feed).
52+
class AblaRuntime {
53+
public:
54+
/// Cold-start: anchor at the activation/floor State for `anchor_height`.
55+
/// Safe default when no BCHN-pinned anchor is available yet.
56+
AblaRuntime(bool is_testnet, uint32_t anchor_height, const HeaderChain& chain)
57+
: m_tracker(AblaTracker::floor_anchored(is_testnet, anchor_height)),
58+
m_feed(m_tracker, chain) {}
59+
60+
/// BCHN-pinned anchor: start from a known-good {height, State} captured at
61+
/// daemon start. Lets the live budget track the real consensus limit from
62+
/// block one instead of climbing from the floor.
63+
AblaRuntime(bool is_testnet, uint32_t anchor_height, abla::State anchor_state,
64+
const HeaderChain& chain)
65+
: m_tracker(is_testnet, anchor_height, anchor_state),
66+
m_feed(m_tracker, chain) {}
67+
68+
AblaRuntime(const AblaRuntime&) = delete;
69+
AblaRuntime& operator=(const AblaRuntime&) = delete;
70+
71+
/// Close the loop: attach the feed to the node`s full_block event and hand
72+
/// the tracker to the EmbeddedCoinNode. Call once, after both exist.
73+
void wire(bch::interfaces::Node& node, EmbeddedCoinNode& embedded) {
74+
m_feed.attach(node);
75+
embedded.set_abla_tracker(&m_tracker);
76+
LOG_INFO << "[EMB-BCH] ABLA runtime wired: full_block -> feed -> tracker"
77+
<< " -> template builder (anchor_height=" << m_tracker.cursor_height()
78+
<< ", budget=" << m_tracker.budget_for_tip(m_tracker.cursor_height())
79+
<< ", " << (m_tracker.is_stale() ? "stale" : "current") << ")";
80+
}
81+
82+
/// Re-establish a known-good anchor after a gap/reorg or on a fresh BCHN
83+
/// pin. Thin passthrough to the tracker; the feed keeps its subscription.
84+
void reanchor(uint32_t height, abla::State state) {
85+
m_tracker.reanchor(height, state);
86+
LOG_INFO << "[EMB-BCH] ABLA runtime reanchored at height=" << height
87+
<< " budget=" << m_tracker.budget_for_tip(height);
88+
}
89+
90+
AblaTracker& tracker() { return m_tracker; }
91+
const AblaTracker& tracker() const { return m_tracker; }
92+
bool is_wired() const { return m_feed.is_attached(); }
93+
94+
private:
95+
AblaTracker m_tracker; // declared first: outlives m_feed + the EmbeddedCoinNode pointer
96+
AblaBlockFeed m_feed;
97+
};
98+
99+
} // namespace coin
100+
} // namespace bch

0 commit comments

Comments
 (0)