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
22 changes: 22 additions & 0 deletions src/impl/dgb/coin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# dgb_coin -- DGB coin-layer library (Path A minimal-stub surface).
# Mirrors src/impl/btc/coin/CMakeLists.txt, listing only the files that exist
# at this milestone. NOT yet referenced by any add_subdirectory(): top-level
# registration of src/impl/dgb follows the ci-steward OBJECT-lib convention
# (see ../CMakeLists.txt); staged here so that wiring is a one-line flip.

set(dgb_coin_impl
rpc_data.hpp
rpc.hpp
node.hpp
coin_node.hpp coin_node.cpp
)

set(dgb_coin_interface
node_interface.hpp
header_chain.hpp
template_builder.hpp
)

add_library(dgb_coin ${dgb_coin_interface} ${dgb_coin_impl})

target_link_libraries(dgb_coin core nlohmann_json::nlohmann_json)
51 changes: 51 additions & 0 deletions src/impl/dgb/coin/coin_node.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "coin_node.hpp"

#include <stdexcept>
#include <utility>

namespace dgb
{

namespace coin
{

core::coin::WorkView CoinNode::get_work_view()
{
// No work source configured at all -> empty view (1:1 with the btc/ltc
// reference).
if (!m_embedded && !m_rpc)
return {};

// Embedded preferred, external RPC fallback. getwork() throws
// std::runtime_error when no template can be produced -- propagated to the
// caller (web_server), matching the ICoinNode contract. On DGB Path A both
// sources are stubs, so this path always throws until M3 lands a real one.
rpc::WorkData wd = m_embedded ? m_embedded->getwork() : m_rpc->getwork();

// Retain the FULL WorkData coin-side. Variable::set takes its argument BY
// VALUE, so this copies wd; sequenced BEFORE the std::move()s below so the
// copy completes first -- never move out of wd beforehand.
work.set(wd);

core::coin::WorkView v;
v.m_data = std::move(wd.m_data);
v.m_hashes = std::move(wd.m_hashes);
v.m_latency = wd.m_latency;
return v;
}

bool CoinNode::submit_block_hex(const std::string& block_hex, bool ignore_failure)
{
// Guard sits ahead of the submit: in embedded-preferred mode m_rpc can be
// null. Returning false is the correct "no RPC sink" result.
if (!m_rpc)
return false;

// DGB's NodeRPC::submit_block_hex is already the agnostic 2-arg/no-mweb
// form (MWEB is LTC-specific and absent here), so we forward directly.
return m_rpc->submit_block_hex(block_hex, ignore_failure);
}

} // namespace coin

} // namespace dgb
70 changes: 70 additions & 0 deletions src/impl/dgb/coin/coin_node.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#pragma once

// ---------------------------------------------------------------------------
// dgb::coin::CoinNode -- concrete core::coin::ICoinNode for DGB (family-1 P2
// WorkView seam, Path A minimal-stub). 1:1 mirror of btc::coin::CoinNode
// (src/impl/btc/coin/coin_node.{hpp,cpp}), which is itself member-mapped from
// the ltc::coin::CoinNode reference -- the control flow / sequencing are the
// load-bearing part and are preserved verbatim:
// m_embedded : CoinNodeInterface* -- embedded in-process source
// m_rpc : NodeRPC* -- external coin-RPC client (STUB)
// work : Variable<rpc::WorkData> -- full per-coin WorkData kept
// coin-side; only the agnostic
// WorkView slice crosses the seam
//
// DGB Path A status: both work sources behind this adapter are stubs --
// NodeRPC throws on getwork() (rpc.hpp) and no EmbeddedCoinNode exists until
// the M3 daemon slice -- so a wired DGB node reports "no template" loudly
// through the ICoinNode contract rather than fabricating work. The adapter
// itself is COMPLETE: when either source becomes real, no seam-side change
// is needed.
//
// Build-INERT: defines the type; NOT yet wired into web_server or a
// main_dgb.cpp (no such binary split exists yet). Registration follows the
// ci-steward OBJECT-lib convention; see src/impl/dgb/CMakeLists.txt.
// ---------------------------------------------------------------------------

#include <string>

#include <core/coin/node_iface.hpp>
#include <core/coin/work_view.hpp>
#include <core/events.hpp>

#include "rpc.hpp"
#include "rpc_data.hpp"
#include "template_builder.hpp"

namespace dgb
{

namespace coin
{

class CoinNode : public core::coin::ICoinNode
{
// Embedded in-process template source (EmbeddedCoinNode, M3). May be null
// when the node runs RPC-only. is_embedded() reports its presence.
CoinNodeInterface* m_embedded = nullptr;

// External coin-RPC client. May be null in embedded-preferred mode; it is
// the sole sink for submit_block_hex(). has_rpc() reports its presence.
NodeRPC* m_rpc = nullptr;

// Full per-coin WorkData retained coin-side via work.set(wd); only the
// agnostic WorkView slice crosses the seam into core/web_server.
Variable<rpc::WorkData> work;

public:
CoinNode(CoinNodeInterface* embedded, NodeRPC* rpc)
: m_embedded(embedded), m_rpc(rpc) {}

core::coin::WorkView get_work_view() override;
bool submit_block_hex(const std::string& block_hex, bool ignore_failure) override;

bool is_embedded() const override { return m_embedded != nullptr; }
bool has_rpc() const override { return m_rpc != nullptr; }
};

} // namespace coin

} // namespace dgb
55 changes: 55 additions & 0 deletions src/impl/dgb/coin/node.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
#pragma once

// ---------------------------------------------------------------------------
// dgb::coin::Node -- per-coin node owner (Path A minimal-stub). TRIMMED mirror
// of src/impl/btc/coin/node.hpp: owns the NodeRPC client and inherits the
// dgb::interfaces::Node shared-state surface (work variable + new_block
// event) that NodeRPC and the seam-side CoinNode bind against.
//
// Deliberately ABSENT until M3 (each needs a port dgb does not have yet):
// - NodeP2P / p2p_connection (coin P2P block relay; btc's p2p_node.hpp)
// - init_rpc() transport connect (NodeRPC is a stub with no transport)
// - submit_block_p2p / send_getheaders / handshake surface
// The ctor keeps btc's (context, config) shape via auto params (no boost
// include needed in the stub) so M3 restores the body without re-typing
// construction sites.
// ---------------------------------------------------------------------------

#include <memory>

#include "node_interface.hpp"
#include "rpc.hpp"

namespace dgb
{

namespace coin
{

template <typename ConfigType>
class Node : public dgb::interfaces::Node
{
using config_t = ConfigType;

config_t* m_config = nullptr;

std::unique_ptr<NodeRPC> m_rpc;

public:
Node(auto* /*context*/, auto* config) : m_config(config)
{
}

void run()
{
// Stub NodeRPC: constructed so has-rpc presence wiring can be
// exercised, but no transport connect until M3.
m_rpc = std::make_unique<NodeRPC>(this);
}

NodeRPC* rpc() { return m_rpc.get(); }
};

} // namespace coin

} // namespace dgb
39 changes: 39 additions & 0 deletions src/impl/dgb/coin/node_interface.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#pragma once

// ---------------------------------------------------------------------------
// dgb::interfaces::Node -- coin-node shared-state surface (Path A
// minimal-stub). Mirrors src/impl/btc/coin/node_interface.hpp TRIMMED to the
// members the family-1 ICoinNode seam actually binds today:
//
// work : Variable<rpc::WorkData> -- get_work result (NodeRPC fills,
// CoinNode retains coin-side per the WorkView seam contract)
// new_block : Event<uint256> -- block-hash announce (header-chain
// feed; uint256 only, no per-coin type needed)
//
// Deliberately ABSENT until the M3 type ports land (each pulls a type dgb
// does not have yet): Event<Transaction> new_tx, Event<vector<
// BlockHeaderType>> new_headers, Event<BlockType> full_block, TXIDCache
// txidcache, known_txs map. Restoring them is additive; nothing in the seam
// depends on their absence.
// ---------------------------------------------------------------------------

#include <core/events.hpp>
#include <core/uint256.hpp>

#include "rpc_data.hpp"

namespace dgb
{

namespace interfaces
{

struct Node
{
Variable<dgb::coin::rpc::WorkData> work; // get_work result
Event<uint256> new_block; // block_hash
};

} // namespace interfaces

} // namespace dgb
65 changes: 65 additions & 0 deletions src/impl/dgb/coin/rpc.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#pragma once

// ---------------------------------------------------------------------------
// dgb::coin::NodeRPC -- external coin-RPC client STUB (Path A minimal-stub,
// "rpc stubs" scope item).
//
// btc/ltc NodeRPC is a boost::beast + jsonrpccxx HTTP JSON-RPC client whose
// header drags in block.hpp / transaction.hpp -- types dgb does not port
// until M3. This stub keeps the call surface coin_node.cpp and coin/node.hpp
// consume, with no transport behind it:
//
// getwork() -> throws std::runtime_error. This is the ICoinNode
// contract for "no template available" -- web_server
// already handles the throw, so a wired-but-stub DGB
// node degrades loudly, not silently.
// submit_block_hex() -> false ("no RPC sink"; the same result the null-
// m_rpc guard in CoinNode::submit_block_hex yields).
// check() -> false (never connected).
//
// connect()/reconnect()/the RPC method set (getblocktemplate etc.) arrive
// with the real transport in M3 as a body-only swap mirroring
// src/impl/btc/coin/rpc.{hpp,cpp}; DGB's getblocktemplate call passes
// rules=["scrypt"] per the Scrypt GBT filter point (template_builder.hpp,
// impl plan section 3) so only Scrypt-eligible templates are returned.
// ---------------------------------------------------------------------------

#include <stdexcept>
#include <string>

#include "node_interface.hpp"
#include "rpc_data.hpp"

namespace dgb
{

namespace coin
{

class NodeRPC
{
// Shared-state surface the real client fills (work variable); the stub
// holds the pointer so the M3 swap does not change construction sites.
dgb::interfaces::Node* m_coin = nullptr;

public:
explicit NodeRPC(dgb::interfaces::Node* coin = nullptr) : m_coin(coin) {}

// Never connected: no transport in the stub.
bool check() const { return false; }

rpc::WorkData getwork()
{
throw std::runtime_error(
"dgb: NodeRPC is a Path A stub -- no external RPC transport until M3");
}

bool submit_block_hex(const std::string& /*block_hex*/, bool /*ignore_failure*/)
{
return false;
}
};

} // namespace coin

} // namespace dgb
63 changes: 63 additions & 0 deletions src/impl/dgb/coin/rpc_data.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#pragma once

// ---------------------------------------------------------------------------
// dgb::coin::rpc::WorkData -- per-coin work payload for the family-1 P2
// WorkView seam (Path A minimal-stub).
//
// Mirrors src/impl/btc/coin/rpc_data.hpp with ONE deliberate trim: btc's
// WorkData carries std::vector<Transaction> m_txs, but DGB has no
// coin/transaction.{hpp,cpp} port yet -- that lands with the M3 embedded
// daemon slice. The ICoinNode seam contract makes the trim safe: web_server
// consumes ONLY the agnostic slice (m_data/m_hashes/m_latency); the full
// per-coin WorkData (incl. txs) never crosses the seam
// (src/core/coin/node_iface.hpp). When the DGB transaction port lands, m_txs
// is restored here and the coin-side work.set(wd) retention in
// CoinNode::get_work_view() carries it without any seam change.
//
// V36 master compat: field semantics match p2pool-merged-v36 getwork result
// (data / txhashes / latency); impl plan section 3 (frstrtr/the, 8ef8d2d).
// ---------------------------------------------------------------------------

#include <ctime>
#include <utility>
#include <vector>

#include <core/uint256.hpp>

#include <nlohmann/json.hpp>

namespace dgb
{

namespace coin
{

namespace rpc
{

struct WorkData
{
nlohmann::json m_data;
std::vector<uint256> m_hashes; // transaction hashes
time_t m_latency = 0;

// TODO(M3): std::vector<Transaction> m_txs once coin/transaction.{hpp,cpp}
// is ported (DGB txs are bitcoin-family; expected near-verbatim from btc's
// port). Kept out of the stub so the rpc chain compiles without the
// Transaction/Block types dgb does not have yet.

WorkData() {}
WorkData(nlohmann::json data, std::vector<uint256> txhashes, time_t latency)
: m_data(std::move(data)), m_hashes(std::move(txhashes)), m_latency(latency)
{
}

bool operator==(const WorkData& rhs) const { return m_data == rhs.m_data; }
bool operator!=(const WorkData& rhs) const { return !(*this == rhs); }
};

} // namespace rpc

} // namespace coin

} // namespace dgb
Loading
Loading