3838#include < impl/dgb/coin/mempool_ingest.hpp>
3939#include < impl/dgb/stratum/work_source.hpp>
4040#include < impl/dgb/coin/p2p_node.hpp>
41+ #include < impl/dgb/coin/rpc.hpp> // NodeRPC — external-daemon submitblock arm (#82)
42+ #include < impl/dgb/coin/rpc_conf.hpp> // digibyte.conf creds resolution (rpcpassword off argv)
43+ #include < impl/dgb/config_coin.hpp> // dgb::CoinParams::MAINNET_RPC_PORT default
4144
4245#include < core/filesystem.hpp>
4346#include < core/stratum_server.hpp>
@@ -135,7 +138,9 @@ int run_node(const core::CoinParams& params, bool testnet,
135138 const std::string& stratum_addr, uint16_t stratum_port,
136139 const std::string& coin_daemon,
137140 const std::vector<std::byte>& coin_magic,
138- const uint256& coin_genesis)
141+ const uint256& coin_genesis,
142+ const std::string& rpc_endpoint,
143+ const std::string& rpc_conf_path)
139144{
140145 io::io_context ioc;
141146
@@ -238,7 +243,42 @@ int run_node(const core::CoinParams& params, bool testnet,
238243 // LOUDLY (the #163 seam guard: no silent drop, INDEPENDENT of the
239244 // embedded source). Point a real NodeRPC at external digibyted here to
240245 // light the submit sink up.
241- dgb::coin::CoinNode coin_node (/* embedded=*/ &embedded_coin, /* rpc=*/ nullptr );
246+ // ── #82 external-daemon submitblock arm (RPC leg of the dual-path
247+ // broadcaster) ── Creds come from digibyte.conf (default
248+ // ~/.digibyte/digibyte.conf, overridable with --coin-rpc-auth PATH) so the
249+ // rpcpassword NEVER touches argv; --coin-rpc HOST:PORT overrides only the
250+ // endpoint. When no creds resolve (no daemon provisioned) the arm stays
251+ // UNARMED (rpc=nullptr) and submit_block_hex returns false LOUDLY (the #163
252+ // CoinNode seam guard) — byte-identical to today's daemon-less default
253+ // build, so --run still works without a digibyted. NodeRPC is declared
254+ // BEFORE coin_node so it OUTLIVES the tracker callback that captures it.
255+ dgb::coin::RpcConf rpc_conf;
256+ {
257+ std::string conf_path = rpc_conf_path;
258+ if (conf_path.empty ()) {
259+ const char * home = std::getenv (" HOME" );
260+ conf_path = std::string (home ? home : " ." ) + " /.digibyte/digibyte.conf" ;
261+ }
262+ if (dgb::coin::load_rpc_conf (conf_path, rpc_conf)) {
263+ if (rpc_conf.port == 0 )
264+ rpc_conf.port = testnet ? dgb::CoinParams::TESTNET_RPC_PORT
265+ : dgb::CoinParams::MAINNET_RPC_PORT ;
266+ dgb::coin::apply_endpoint_override (rpc_endpoint, rpc_conf);
267+ }
268+ }
269+ std::unique_ptr<dgb::coin::NodeRPC> rpc;
270+ if (rpc_conf.armed ()) {
271+ rpc = std::make_unique<dgb::coin::NodeRPC>(&ioc, /* coin=*/ nullptr , testnet);
272+ rpc->connect (NetService (rpc_conf.host , rpc_conf.port ), rpc_conf.userpass ());
273+ std::cout << " [DGB] external-daemon submit arm ARMED: NodeRPC -> "
274+ << rpc_conf.host << " :" << rpc_conf.port
275+ << " (creds from digibyte.conf)" << std::endl;
276+ } else {
277+ std::cout << " [DGB] external-daemon submit arm UNARMED "
278+ " (no digibyte.conf creds; embedded-only submit path)" << std::endl;
279+ }
280+
281+ dgb::coin::CoinNode coin_node (/* embedded=*/ &embedded_coin, /* rpc=*/ rpc.get ());
242282
243283 dgb::Node p2p_node (&ioc, &config);
244284 p2p_node.set_target_outbound_peers (4 );
@@ -483,6 +523,8 @@ int main(int argc, char** argv)
483523 std::string coin_daemon; // --coin-daemon HOST:PORT (embedded P2P producer target)
484524 std::vector<std::byte> coin_magic; // --coin-magic HEX (network pchMessageStart)
485525 uint256 coin_genesis; // --coin-genesis HASH (initial getheaders locator base)
526+ std::string rpc_endpoint; // --coin-rpc HOST:PORT (external digibyted submit arm)
527+ std::string rpc_conf_path; // --coin-rpc-auth PATH to digibyte.conf (creds source)
486528 for (int i = 1 ; i < argc; ++i) {
487529 if (std::strcmp (argv[i], " --version" ) == 0 ) {
488530 std::cout << " c2pool-dgb " << C2POOL_VERSION << " \n " ;
@@ -511,6 +553,12 @@ int main(int argc, char** argv)
511553 if (std::strcmp (argv[i], " --coin-genesis" ) == 0 && i + 1 < argc) {
512554 coin_genesis = uint256S (argv[++i]); // genesis hash for initial getheaders
513555 }
556+ if (std::strcmp (argv[i], " --coin-rpc" ) == 0 && i + 1 < argc) {
557+ rpc_endpoint = argv[++i]; // HOST:PORT endpoint override (no secret)
558+ }
559+ if (std::strcmp (argv[i], " --coin-rpc-auth" ) == 0 && i + 1 < argc) {
560+ rpc_conf_path = argv[++i]; // path to digibyte.conf (rpcpassword stays in-file)
561+ }
514562 }
515563
516564 const core::CoinParams params = dgb::make_coin_params (/* testnet=*/ false );
@@ -522,7 +570,8 @@ int main(int argc, char** argv)
522570 // --run: stand up the run-loop (io_context + sharechain peer + stratum).
523571 if (want_run)
524572 return run_node (params, /* testnet=*/ false , stratum_addr, stratum_port,
525- coin_daemon, coin_magic, coin_genesis);
573+ coin_daemon, coin_magic, coin_genesis,
574+ rpc_endpoint, rpc_conf_path);
526575
527576 // --selftest, or a bare invocation: drive the live score path so the
528577 // binary exercises real consensus code, then exit cleanly.
0 commit comments