Skip to content

Commit 7d14eef

Browse files
committed
bch(m5): fold master ee7d405 (#133 M5 share-layer landed) into embedded-body lane
Non-destructive merge of origin/master into bch/m5-embedded-body-wip to keep the embedded daemon body lane on current master. No force-push, shared history preserved. External-RPC fallback retained.
2 parents 66166bb + ee7d405 commit 7d14eef

30 files changed

Lines changed: 5481 additions & 165 deletions

.github/workflows/build.yml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
run: conan install . --build=missing --output-folder=build_ci --settings=build_type=Release
4545

4646
- name: Configure
47-
run: cmake -S . -B build_ci -DCMAKE_TOOLCHAIN_FILE=build_ci/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
47+
run: cmake -S . -B build_ci -DCMAKE_TOOLCHAIN_FILE=build_ci/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DCOIN_DGB=ON
4848

4949
- name: Build
5050
run: cmake --build build_ci --target c2pool -j$(nproc)
@@ -67,7 +67,8 @@ jobs:
6767
test_phase4_embedded \
6868
test_mweb_builder \
6969
test_address_resolution test_compute_share_target \
70-
test_utxo test_dgb_subsidy \
70+
test_utxo test_dgb_subsidy dgb_share_test \
71+
rpc_request_test softfork_check_test genesis_check_test \
7172
v37_test \
7273
-j$(nproc)
7374
@@ -171,6 +172,7 @@ jobs:
171172
cmake -S . -B build_asan \
172173
-DCMAKE_TOOLCHAIN_FILE=build_asan/conan_toolchain.cmake \
173174
-DCMAKE_BUILD_TYPE=Release \
175+
-DCOIN_DGB=ON \
174176
-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-sanitize=vptr -fno-omit-frame-pointer -fno-sanitize-recover=undefined -g" \
175177
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined -fno-sanitize=vptr" \
176178
-DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address,undefined -fno-sanitize=vptr"
@@ -193,7 +195,8 @@ jobs:
193195
test_phase4_embedded \
194196
test_mweb_builder \
195197
test_address_resolution test_compute_share_target \
196-
test_utxo test_dgb_subsidy \
198+
test_utxo test_dgb_subsidy dgb_share_test \
199+
rpc_request_test softfork_check_test genesis_check_test \
197200
test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
198201
v37_test \
199202
-j$(nproc)

src/c2pool/CMakeLists.txt

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,27 @@ target_link_libraries(c2pool-btc
170170
# stratum_server.o, which reference merged/payout/hashrate/ltc symbols (the
171171
# self-link tangle that forces c2pool-btc to drag in ltc/payout/merged) and
172172
# would pull Phase B forward. We therefore add ONLY yaml-cpp (header path).
173-
# Link deps stay at yaml-cpp + json + Boost until Phase B.
173+
# EXE-WIRE slice: main_dgb.cpp drives the LIVE header-only chain-score path
174+
# (dgb::ShareTracker::score, #132/#134) + make_coin_params; it never constructs
175+
# the abstract dgb::NodeImpl, so node.cpp (the run-loop TU that references core
176+
# web_server/stratum -> payout/merged/hashrate/ltc, i.e. the Phase B self-link
177+
# tangle AND merged-mining = DOGE aux, which is NOT in the V36 default DGB
178+
# build) is intentionally NOT compiled in. core is an OBJECT lib (links ALL its
179+
# objects unconditionally, incl. web_server/stratum), so linking it forces that
180+
# whole tangle; we therefore do NOT link core. We compile ONLY core/uint256.cpp
181+
# directly (base_uint symbols the header-only ScoreT/hashrate-hex path needs) -
182+
# additive, no other target touched - and link nothing beyond yaml-cpp(header)/
183+
# json/Boost. Per-coin isolation held. The embedded run-loop (NodeBridge over
184+
# digibyted P2P + Stratum) and its pool-runtime link land in a later Phase B
185+
# slice.
174186
add_executable(c2pool-dgb
175187
main_dgb.cpp
176-
${CMAKE_SOURCE_DIR}/src/impl/dgb/node.cpp
188+
${CMAKE_SOURCE_DIR}/src/core/uint256.cpp
177189
)
178190
target_compile_definitions(c2pool-dgb PRIVATE C2POOL_VERSION="${C2POOL_GIT_VERSION}")
179191
target_link_libraries(c2pool-dgb
180-
yaml-cpp::yaml-cpp # include dir only: config_{coin,pool}.hpp -> core/netaddress.hpp -> <yaml-cpp/yaml.h>
192+
btclibs # STATIC util lib: HexStr/HexDigit (strencodings) for base_uint hex - pure utility, no pool runtime
193+
yaml-cpp::yaml-cpp # config_{coin,pool}.hpp -> core/netaddress.hpp -> <yaml-cpp/yaml.h>
181194
nlohmann_json::nlohmann_json
182195
${Boost_LIBRARIES}
183196
)

src/c2pool/main_dgb.cpp

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,112 @@
11
// c2pool-dgb — DigiByte Scrypt-only (V36) p2pool node entry point.
22
//
3-
// SLICE #4 (Option B): genuinely minimal COMPILING SKELETON. This wires the
4-
// CMake c2pool-dgb target so the binary builds + links off master; it does
5-
// NOT yet run a node. The embedded-daemon + pool/sharechain body is M3 /
6-
// Phase B (DGB = PORT-not-activation; Phase A p2p+mempool already landed under
7-
// impl/dgb/coin/). When the pool-pillars node.cpp lands it replaces the
8-
// skeleton via a clean dgb-only re-cut off master.
3+
// Wires the real dgb sharechain/pool TU (pool pillars + score path, ported from
4+
// LTC under impl/dgb/ across PRs #112/#113/#115/#121/#129/#131/#132/#134) into
5+
// the c2pool-dgb executable. This is the exe-wire slice: it replaces the
6+
// slice-#4 skeleton entry (dgb::run_skeleton/network_summary, removed when #134
7+
// dropped the real node.cpp in) and drives the LIVE chain-score path at
8+
// startup, so the coin smoke gate exercises share_tracker::score() rather than
9+
// merely linking it. node.cpp (the concrete dgb::NodeImpl) is compiled into the
10+
// target so the real node TU links; its full run-loop (NodeBridge over the
11+
// embedded digibyted P2P + Stratum) is a later Phase B slice — dgb::NodeImpl is
12+
// abstract (ICommunicator::handle is supplied by the NodeBridge wrapper), so a
13+
// bare node is not stood up here. The score path lives on dgb::ShareTracker,
14+
// which we drive directly (header-only, no network / no LevelDB).
915
//
1016
// V36 scope: Scrypt blocks validated; the other 4 DGB algos (SHA256d, Skein,
11-
// Qubit, Odocrypt) are accept-by-continuity / ignored — full 5-algo support
12-
// is V37. Compatibility target: frstrtr/p2pool-merged-v36 (share format,
13-
// sharechain rules, PPLNS, Stratum, block submission). See
14-
// c2pool-dgb-embedded-impl-plan.md (frstrtr/the docs/v36).
15-
//
16-
// Mirrors src/c2pool/main_btc.cpp's target shape, pruned to a stub entry.
17+
// Qubit, Odocrypt) are accept-by-continuity / ignored — full 5-algo support is
18+
// V37. Conformance oracle: frstrtr/p2pool-dgb-scrypt (DGB-Scrypt standalone
19+
// parent; merged-v36 byte-compat WAIVED for DGB per operator 2026-06-17).
20+
// CoinParams are oracle-sourced via dgb::make_coin_params (no hardcoded bytes).
21+
// Mirrors src/c2pool/main_btc.cpp's target shape.
1722

1823
#include <impl/dgb/node.hpp>
1924

25+
#include <cstdint>
2026
#include <cstring>
2127
#include <iostream>
28+
#include <string>
2229

2330
#ifndef C2POOL_VERSION
2431
#define C2POOL_VERSION "dev"
2532
#endif
2633

2734
namespace {
2835

29-
void print_banner(const char* argv0)
36+
// Live network summary sourced from the oracle-populated CoinParams
37+
// (make_coin_params) — never a hardcoded string. These are the exact constants
38+
// the sharechain score() consumes (block_period etc.).
39+
std::string network_summary(const core::CoinParams& p)
40+
{
41+
return "DigiByte (Scrypt-only) — identifier=" + p.active_identifier_hex()
42+
+ " prefix=" + p.active_prefix_hex()
43+
+ " block_period=" + std::to_string(p.block_period) + "s"
44+
+ " share_period=" + std::to_string(p.share_period) + "s"
45+
+ " chain_length=" + std::to_string(p.chain_length);
46+
}
47+
48+
void print_banner(const char* argv0, const core::CoinParams& p)
3049
{
3150
std::cout
3251
<< "c2pool-dgb " << C2POOL_VERSION << " — DigiByte Scrypt-only (V36)\n\n"
33-
<< "Usage: " << argv0 << " [--version] [--help]\n\n"
34-
<< "Status: skeleton (slice #4). The node run-loop (embedded daemon +\n"
35-
<< " pool pillars) lands in M3 / Phase B.\n"
36-
<< "Network: " << dgb::network_summary() << "\n";
52+
<< "Usage: " << argv0 << " [--version] [--help] [--selftest]\n\n"
53+
<< "Status: pool/sharechain pillars live (Phase B). The embedded-daemon\n"
54+
<< " run-loop (digibyted P2P + Stratum) lands in a later slice;\n"
55+
<< " external digibyted RPC stays as a fallback.\n"
56+
<< "Network: " << network_summary(p) << "\n";
57+
}
58+
59+
// Drive the LIVE chain-score path: dgb::ShareTracker::score() derives time_span
60+
// from CoinParams::block_period (PR #132) and total_work from the verified
61+
// chain. On an empty verified set score() takes its short-chain early-return,
62+
// but the call EXECUTES the real score() body compiled from the #132/#134
63+
// sharechain TU (not just links it) and reports the oracle block_period it
64+
// consumes. The deep block_period multiply (time_span = confirmations *
65+
// block_period) runs once a verified chain >= chain_length exists — exercised
66+
// by the Phase B share fixtures, not standable-up in a startup smoke.
67+
int run_selftest(const core::CoinParams& params)
68+
{
69+
dgb::ShareTracker tracker;
70+
tracker.m_params = &params; // wiring NodeImpl does at ctor time
71+
72+
// No embedded daemon wired here → block height is "unknown" (0), which
73+
// routes score() through its 1e6-confirmation * block_period fallback.
74+
auto block_rel_height = [](uint256) -> std::int32_t { return 0; };
75+
76+
auto s = tracker.score(uint256::ZERO, block_rel_height);
77+
std::cout << "[selftest] live dgb::ShareTracker constructed; score() driven\n"
78+
<< "[selftest] score(ZERO) -> chain_len=" << s.chain_len
79+
<< " hashrate=" << (s.hashrate.IsNull() ? std::string("0")
80+
: s.hashrate.GetHex()) << "\n"
81+
<< "[selftest] time_span basis block_period=" << params.block_period
82+
<< "s (oracle PARENT.BLOCK_PERIOD, #132 SSOT)\n"
83+
<< "[selftest] OK\n";
84+
return 0;
3785
}
3886

3987
} // namespace
4088

4189
int main(int argc, char** argv)
4290
{
91+
bool want_help = false;
92+
bool want_selftest = false;
4393
for (int i = 1; i < argc; ++i) {
4494
if (std::strcmp(argv[i], "--version") == 0) {
4595
std::cout << "c2pool-dgb " << C2POOL_VERSION << "\n";
4696
return 0;
4797
}
48-
if (std::strcmp(argv[i], "--help") == 0) {
49-
print_banner(argv[0]);
50-
return 0;
51-
}
98+
if (std::strcmp(argv[i], "--help") == 0) want_help = true;
99+
if (std::strcmp(argv[i], "--selftest") == 0) want_selftest = true;
52100
}
53101

54-
print_banner(argv[0]);
55-
return dgb::run_skeleton();
102+
const core::CoinParams params = dgb::make_coin_params(/*testnet=*/false);
103+
print_banner(argv[0], params);
104+
105+
if (want_help)
106+
return 0;
107+
108+
// --selftest, or a bare invocation (no run-loop yet): drive the live score
109+
// path so the binary exercises real consensus code, then exit cleanly.
110+
(void)want_selftest;
111+
return run_selftest(params);
56112
}

src/core/version_gate.hpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#pragma once
2+
//
3+
// version_gate.hpp — Cross-coin c2pool share-version activation gate (SINGLE SOURCE OF TRUTH).
4+
//
5+
// c2pool's sharechain format is versioned. The V36 format revision is a
6+
// CONSENSUS boundary that is IDENTICAL across every coin c2pool mines
7+
// (btc/ltc/bch/dgb): when a share's VERSION >= 36 the wire layout switches to
8+
// the V36 encoding (VarInt subsidy, AbsworkV36Format, merged_addresses,
9+
// merged_coinbase_info + merged_payout_hash, V36HashLinkType extra_data,
10+
// message_data) and the V36 PPLNS / donation semantics engage. The activation
11+
// number 36 carries no per-coin network state — every coin's params set
12+
// current_share_version = 36 — so it belongs here in core/ rather than being
13+
// re-spelled as a bare `>= 36` literal at each call site.
14+
//
15+
// SCOPE — what this gate does and does NOT own:
16+
// OWNS: the V36 share-format / consensus-revision boundary (uniform 36).
17+
// NOT: segwit activation. That version is coin-SPECIFIC
18+
// (BTC 33, dgb 35, ltc/bch 17) and stays in each coin's PoolConfig
19+
// as SEGWIT_ACTIVATION_VERSION, surfaced via the per-coin
20+
// is_segwit_activated() helper. Do not fold segwit into this gate.
21+
//
22+
// Conformance shape (BTC-first, per v36-standardize goal):
23+
// Every coin replaces its scattered `version >= 36` / `>= 36` literals with
24+
// core::version_gate::is_v36_active(version). Both compile-time
25+
// (`if constexpr (is_v36_active(Tmpl::version))`) and runtime
26+
// (`if (is_v36_active(p.share_version))`) call sites are covered because the
27+
// predicate is constexpr. BTC is the reference adoption; ltc/dgb/bch conform
28+
// by mechanical site-rewrite — no value changes, byte-for-byte identical gate.
29+
//
30+
// Provenance: p2pool check() gates the V36 share rev on self.VERSION >= 36
31+
// (jtoomim/forrestv). The number is shared across the c2pool multi-coin tree.
32+
//
33+
34+
#include <cstdint>
35+
36+
namespace core::version_gate
37+
{
38+
39+
// V36 share-format / consensus-revision activation version. Uniform cross-coin.
40+
inline constexpr uint64_t V36_ACTIVATION_VERSION = 36;
41+
42+
// True iff a share of the given VERSION uses the V36 sharechain encoding and
43+
// V36 consensus semantics. constexpr so it serves both `if constexpr` template
44+
// gates and runtime checks.
45+
constexpr bool is_v36_active(uint64_t version)
46+
{
47+
return version >= V36_ACTIVATION_VERSION;
48+
}
49+
50+
} // namespace core::version_gate

src/impl/btc/share.hpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "coin/block.hpp"
44
#include "share_types.hpp"
5+
#include <core/version_gate.hpp> // SSOT: core::version_gate::is_v36_active
56

67
#include <sharechain/sharechain.hpp>
78
#include <sharechain/share.hpp>
@@ -159,7 +160,7 @@ struct Formatter
159160
);
160161

161162
// Address handling — version-dependent
162-
if constexpr (version >= 36)
163+
if constexpr (core::version_gate::is_v36_active(version))
163164
{
164165
READWRITE(obj->m_pubkey_hash); // IntType(160)
165166
READWRITE(obj->m_pubkey_type); // IntType(8)
@@ -174,7 +175,7 @@ struct Formatter
174175
}
175176

176177
// Subsidy — V36 uses VarInt, others use fixed uint64
177-
if constexpr (version >= 36)
178+
if constexpr (core::version_gate::is_v36_active(version))
178179
{
179180
READWRITE(VarInt(obj->m_subsidy));
180181
}
@@ -195,7 +196,7 @@ struct Formatter
195196
}
196197

197198
// V36: merged_addresses (after segwit_data, before far_share_hash)
198-
if constexpr (version >= 36)
199+
if constexpr (core::version_gate::is_v36_active(version))
199200
{
200201
READWRITE(obj->m_merged_addresses);
201202
}
@@ -214,7 +215,7 @@ struct Formatter
214215
);
215216

216217
// Abswork — V36 uses VarInt-encoded uint64, others use fixed uint128
217-
if constexpr (version >= 36)
218+
if constexpr (core::version_gate::is_v36_active(version))
218219
{
219220
READWRITE(Using<AbsworkV36Format>(obj->m_abswork));
220221
}
@@ -224,7 +225,7 @@ struct Formatter
224225
}
225226

226227
// V36: merged_coinbase_info + merged_payout_hash (after abswork)
227-
if constexpr (version >= 36)
228+
if constexpr (core::version_gate::is_v36_active(version))
228229
{
229230
READWRITE(obj->m_merged_coinbase_info);
230231
READWRITE(obj->m_merged_payout_hash);
@@ -244,7 +245,7 @@ struct Formatter
244245
);
245246

246247
// V36: message_data (at the end)
247-
if constexpr (version >= 36)
248+
if constexpr (core::version_gate::is_v36_active(version))
248249
{
249250
READWRITE(obj->m_message_data);
250251
}

0 commit comments

Comments
 (0)