Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
run: conan install . --build=missing --output-folder=build_ci --settings=build_type=Release

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

- name: Build
run: cmake --build build_ci --target c2pool -j$(nproc)
Expand All @@ -67,7 +67,7 @@ jobs:
test_phase4_embedded \
test_mweb_builder \
test_address_resolution test_compute_share_target \
test_utxo test_dgb_subsidy \
test_utxo test_dgb_subsidy dgb_share_test \
v37_test \
-j$(nproc)

Expand Down Expand Up @@ -171,6 +171,7 @@ jobs:
cmake -S . -B build_asan \
-DCMAKE_TOOLCHAIN_FILE=build_asan/conan_toolchain.cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCOIN_DGB=ON \
-DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-sanitize=vptr -fno-omit-frame-pointer -fno-sanitize-recover=undefined -g" \
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address,undefined -fno-sanitize=vptr" \
-DCMAKE_SHARED_LINKER_FLAGS="-fsanitize=address,undefined -fno-sanitize=vptr"
Expand All @@ -193,7 +194,7 @@ jobs:
test_phase4_embedded \
test_mweb_builder \
test_address_resolution test_compute_share_target \
test_utxo test_dgb_subsidy \
test_utxo test_dgb_subsidy dgb_share_test \
test_coin_broadcaster test_multiaddress_pplns test_pplns_stress \
v37_test \
-j$(nproc)
Expand Down
19 changes: 16 additions & 3 deletions src/c2pool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,27 @@ target_link_libraries(c2pool-btc
# stratum_server.o, which reference merged/payout/hashrate/ltc symbols (the
# self-link tangle that forces c2pool-btc to drag in ltc/payout/merged) and
# would pull Phase B forward. We therefore add ONLY yaml-cpp (header path).
# Link deps stay at yaml-cpp + json + Boost until Phase B.
# EXE-WIRE slice: main_dgb.cpp drives the LIVE header-only chain-score path
# (dgb::ShareTracker::score, #132/#134) + make_coin_params; it never constructs
# the abstract dgb::NodeImpl, so node.cpp (the run-loop TU that references core
# web_server/stratum -> payout/merged/hashrate/ltc, i.e. the Phase B self-link
# tangle AND merged-mining = DOGE aux, which is NOT in the V36 default DGB
# build) is intentionally NOT compiled in. core is an OBJECT lib (links ALL its
# objects unconditionally, incl. web_server/stratum), so linking it forces that
# whole tangle; we therefore do NOT link core. We compile ONLY core/uint256.cpp
# directly (base_uint symbols the header-only ScoreT/hashrate-hex path needs) -
# additive, no other target touched - and link nothing beyond yaml-cpp(header)/
# json/Boost. Per-coin isolation held. The embedded run-loop (NodeBridge over
# digibyted P2P + Stratum) and its pool-runtime link land in a later Phase B
# slice.
add_executable(c2pool-dgb
main_dgb.cpp
${CMAKE_SOURCE_DIR}/src/impl/dgb/node.cpp
${CMAKE_SOURCE_DIR}/src/core/uint256.cpp
)
target_compile_definitions(c2pool-dgb PRIVATE C2POOL_VERSION="${C2POOL_GIT_VERSION}")
target_link_libraries(c2pool-dgb
yaml-cpp::yaml-cpp # include dir only: config_{coin,pool}.hpp -> core/netaddress.hpp -> <yaml-cpp/yaml.h>
btclibs # STATIC util lib: HexStr/HexDigit (strencodings) for base_uint hex - pure utility, no pool runtime
yaml-cpp::yaml-cpp # config_{coin,pool}.hpp -> core/netaddress.hpp -> <yaml-cpp/yaml.h>
nlohmann_json::nlohmann_json
${Boost_LIBRARIES}
)
Expand Down
102 changes: 79 additions & 23 deletions src/c2pool/main_dgb.cpp
Original file line number Diff line number Diff line change
@@ -1,56 +1,112 @@
// c2pool-dgb — DigiByte Scrypt-only (V36) p2pool node entry point.
//
// SLICE #4 (Option B): genuinely minimal COMPILING SKELETON. This wires the
// CMake c2pool-dgb target so the binary builds + links off master; it does
// NOT yet run a node. The embedded-daemon + pool/sharechain body is M3 /
// Phase B (DGB = PORT-not-activation; Phase A p2p+mempool already landed under
// impl/dgb/coin/). When the pool-pillars node.cpp lands it replaces the
// skeleton via a clean dgb-only re-cut off master.
// Wires the real dgb sharechain/pool TU (pool pillars + score path, ported from
// LTC under impl/dgb/ across PRs #112/#113/#115/#121/#129/#131/#132/#134) into
// the c2pool-dgb executable. This is the exe-wire slice: it replaces the
// slice-#4 skeleton entry (dgb::run_skeleton/network_summary, removed when #134
// dropped the real node.cpp in) and drives the LIVE chain-score path at
// startup, so the coin smoke gate exercises share_tracker::score() rather than
// merely linking it. node.cpp (the concrete dgb::NodeImpl) is compiled into the
// target so the real node TU links; its full run-loop (NodeBridge over the
// embedded digibyted P2P + Stratum) is a later Phase B slice — dgb::NodeImpl is
// abstract (ICommunicator::handle is supplied by the NodeBridge wrapper), so a
// bare node is not stood up here. The score path lives on dgb::ShareTracker,
// which we drive directly (header-only, no network / no LevelDB).
//
// V36 scope: Scrypt blocks validated; the other 4 DGB algos (SHA256d, Skein,
// Qubit, Odocrypt) are accept-by-continuity / ignored — full 5-algo support
// is V37. Compatibility target: frstrtr/p2pool-merged-v36 (share format,
// sharechain rules, PPLNS, Stratum, block submission). See
// c2pool-dgb-embedded-impl-plan.md (frstrtr/the docs/v36).
//
// Mirrors src/c2pool/main_btc.cpp's target shape, pruned to a stub entry.
// Qubit, Odocrypt) are accept-by-continuity / ignored — full 5-algo support is
// V37. Conformance oracle: frstrtr/p2pool-dgb-scrypt (DGB-Scrypt standalone
// parent; merged-v36 byte-compat WAIVED for DGB per operator 2026-06-17).
// CoinParams are oracle-sourced via dgb::make_coin_params (no hardcoded bytes).
// Mirrors src/c2pool/main_btc.cpp's target shape.

#include <impl/dgb/node.hpp>

#include <cstdint>
#include <cstring>
#include <iostream>
#include <string>

#ifndef C2POOL_VERSION
#define C2POOL_VERSION "dev"
#endif

namespace {

void print_banner(const char* argv0)
// Live network summary sourced from the oracle-populated CoinParams
// (make_coin_params) — never a hardcoded string. These are the exact constants
// the sharechain score() consumes (block_period etc.).
std::string network_summary(const core::CoinParams& p)
{
return "DigiByte (Scrypt-only) — identifier=" + p.active_identifier_hex()
+ " prefix=" + p.active_prefix_hex()
+ " block_period=" + std::to_string(p.block_period) + "s"
+ " share_period=" + std::to_string(p.share_period) + "s"
+ " chain_length=" + std::to_string(p.chain_length);
}

void print_banner(const char* argv0, const core::CoinParams& p)
{
std::cout
<< "c2pool-dgb " << C2POOL_VERSION << " — DigiByte Scrypt-only (V36)\n\n"
<< "Usage: " << argv0 << " [--version] [--help]\n\n"
<< "Status: skeleton (slice #4). The node run-loop (embedded daemon +\n"
<< " pool pillars) lands in M3 / Phase B.\n"
<< "Network: " << dgb::network_summary() << "\n";
<< "Usage: " << argv0 << " [--version] [--help] [--selftest]\n\n"
<< "Status: pool/sharechain pillars live (Phase B). The embedded-daemon\n"
<< " run-loop (digibyted P2P + Stratum) lands in a later slice;\n"
<< " external digibyted RPC stays as a fallback.\n"
<< "Network: " << network_summary(p) << "\n";
}

// Drive the LIVE chain-score path: dgb::ShareTracker::score() derives time_span
// from CoinParams::block_period (PR #132) and total_work from the verified
// chain. On an empty verified set score() takes its short-chain early-return,
// but the call EXECUTES the real score() body compiled from the #132/#134
// sharechain TU (not just links it) and reports the oracle block_period it
// consumes. The deep block_period multiply (time_span = confirmations *
// block_period) runs once a verified chain >= chain_length exists — exercised
// by the Phase B share fixtures, not standable-up in a startup smoke.
int run_selftest(const core::CoinParams& params)
{
dgb::ShareTracker tracker;
tracker.m_params = &params; // wiring NodeImpl does at ctor time

// No embedded daemon wired here → block height is "unknown" (0), which
// routes score() through its 1e6-confirmation * block_period fallback.
auto block_rel_height = [](uint256) -> std::int32_t { return 0; };

auto s = tracker.score(uint256::ZERO, block_rel_height);
std::cout << "[selftest] live dgb::ShareTracker constructed; score() driven\n"
<< "[selftest] score(ZERO) -> chain_len=" << s.chain_len
<< " hashrate=" << (s.hashrate.IsNull() ? std::string("0")
: s.hashrate.GetHex()) << "\n"
<< "[selftest] time_span basis block_period=" << params.block_period
<< "s (oracle PARENT.BLOCK_PERIOD, #132 SSOT)\n"
<< "[selftest] OK\n";
return 0;
}

} // namespace

int main(int argc, char** argv)
{
bool want_help = false;
bool want_selftest = false;
for (int i = 1; i < argc; ++i) {
if (std::strcmp(argv[i], "--version") == 0) {
std::cout << "c2pool-dgb " << C2POOL_VERSION << "\n";
return 0;
}
if (std::strcmp(argv[i], "--help") == 0) {
print_banner(argv[0]);
return 0;
}
if (std::strcmp(argv[i], "--help") == 0) want_help = true;
if (std::strcmp(argv[i], "--selftest") == 0) want_selftest = true;
}

print_banner(argv[0]);
return dgb::run_skeleton();
const core::CoinParams params = dgb::make_coin_params(/*testnet=*/false);
print_banner(argv[0], params);

if (want_help)
return 0;

// --selftest, or a bare invocation (no run-loop yet): drive the live score
// path so the binary exercises real consensus code, then exit cleanly.
(void)want_selftest;
return run_selftest(params);
}
19 changes: 17 additions & 2 deletions src/impl/dgb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,23 @@
# slice under daemon/. Top-level add_subdirectory(src/impl/dgb) registration
# follows the OBJECT-lib convention PR; held ~2-3 heartbeats, not raced here.
if(COIN_DGB)
message(STATUS "c2pool: DGB Scrypt-only coin module enabled (skeleton)")
message(STATUS "c2pool: DGB Scrypt-only coin module enabled")
add_subdirectory(coin)
# add_subdirectory(daemon)
# add_subdirectory(test)
add_subdirectory(test)

# dgb -- DGB Scrypt pool-layer OBJECT lib. Mirrors the ltc OBJECT lib
# (src/impl/ltc/CMakeLists.txt): compiles the real NodeImpl translation unit
# (node.cpp + protocol handlers) so share_tracker.hpp / share_check.hpp are
# pulled into a compiled TU. Links the shared core / pool / sharechain base
# plus dgb_coin (embedded P2P+mempool) and c2pool_storage (LevelDB sharechain).
add_library(dgb OBJECT
config_coin.hpp config_coin.cpp config_pool.hpp config_pool.cpp
node.hpp node.cpp
peer.hpp
protocol_actual.cpp protocol_legacy.cpp
messages.hpp
share_types.hpp share.hpp
)
target_link_libraries(dgb core pool sharechain dgb_coin btclibs c2pool_storage ${SECP256K1_LIBRARIES})
endif()
35 changes: 35 additions & 0 deletions src/impl/dgb/config_coin.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "config_coin.hpp"

#include <btclibs/util/strencodings.h>

namespace dgb
{

std::ofstream& CoinConfig::get_default(std::ofstream& file)
{
YAML::Node out;

out["symbol"] = "defaultNet";
out["p2p"] = config::P2PData();
out["rpc"] = config::RPCData();
out["share_period"] = 0;
out["testnet"] = false;

file << out;
return file;
}

void CoinConfig::load()
{
YAML::Node node = YAML::LoadFile(m_filepath.string());

PARSE_CONFIG(node, symbol, std::string);

m_p2p = node["p2p"].as<config::P2PData>();
m_rpc = node["rpc"].as<config::RPCData>();

PARSE_CONFIG(node, share_period, int);
PARSE_CONFIG(node, testnet, bool);
}

} // namespace dgb
46 changes: 46 additions & 0 deletions src/impl/dgb/config_coin.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#include <core/fileconfig.hpp>
#include <core/netaddress.hpp>

#include <yaml-cpp/yaml.h>
#include <btclibs/util/strencodings.h>

#include <cstdint>
#include <algorithm>

Expand All @@ -25,6 +28,49 @@ namespace config
};

} // config
} // namespace dgb

namespace YAML
{
template<> struct convert<dgb::config::P2PData>
{
static Node encode(const dgb::config::P2PData& rhs)
{
Node node;
node["prefix"] = HexStr(rhs.prefix);
node["address"] = rhs.address;
return node;
}

static bool decode(const Node& node, dgb::config::P2PData& rhs)
{
rhs.prefix = ParseHexBytes(node["prefix"].as<std::string>());
rhs.address = node["address"].as<NetService>();
return true;
}
};

template<> struct convert<dgb::config::RPCData>
{
static Node encode(const dgb::config::RPCData& rhs)
{
Node node;
node["address"] = rhs.address;
node["userpass"] = rhs.userpass;
return node;
}

static bool decode(const Node& node, dgb::config::RPCData& rhs)
{
rhs.address = node["address"].as<NetService>();
rhs.userpass = node["userpass"].as<std::string>();
return true;
}
};
}

namespace dgb
{

/// DigiByte Scrypt coin parameters.
/// Source of truth: p2pool-dgb-scrypt oracle bitcoin/networks/digibyte.py
Expand Down
48 changes: 48 additions & 0 deletions src/impl/dgb/config_pool.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "config_pool.hpp"

#include <btclibs/util/strencodings.h>
#include <yaml-cpp/yaml.h>

namespace dgb
{

std::ofstream& PoolConfig::get_default(std::ofstream& file)
{
YAML::Node out;

// Use the canonical LTC p2pool mainnet prefix when no prefix is set yet
out["prefix"] = m_prefix.empty() ? DEFAULT_PREFIX_HEX : HexStr(m_prefix);
out["worker"] = m_worker;

YAML::Node addrs_node;
for (const auto& host : DEFAULT_BOOTSTRAP_HOSTS)
addrs_node.push_back(host + ":" + std::to_string(P2P_PORT));
out["bootstrap_addrs"] = addrs_node;

file << out;
return file;
}

void PoolConfig::load()
{
YAML::Node node = YAML::LoadFile(m_filepath.string());

// prefix
m_prefix = ParseHexBytes(node["prefix"].as<std::string>());

PARSE_CONFIG(node, worker, std::string);

// Bootstrap addresses: load from YAML if present, otherwise use hardcoded defaults
if (node["bootstrap_addrs"] && node["bootstrap_addrs"].IsSequence())
{
for (const auto& item : node["bootstrap_addrs"])
m_bootstrap_addrs.emplace_back(item.as<std::string>());
}
else
{
for (const auto& host : DEFAULT_BOOTSTRAP_HOSTS)
m_bootstrap_addrs.emplace_back(host + ":" + std::to_string(P2P_PORT));
}
}

} // namespace dgb
Loading
Loading