3434#include < impl/bch/coin/regtest_block.hpp>
3535#include < impl/bch/coin/rpc.hpp>
3636#include < impl/bch/coin/node.hpp>
37+ #include < impl/bch/pool_entrypoint.hpp>
38+ #include < btclibs/util/strencodings.h> // ParseHexBytes (sharechain prefix)
3739
3840#include < core/core_util.hpp>
3941
@@ -71,7 +73,8 @@ void print_banner(const char* argv0)
7173 << " " << argv0 << " --ibd [--testnet] [--near-tip] [--auto-kick] [--peer HOST:PORT] [--max-seconds N]\n "
7274 << " " << argv0 << " --with-peer-verify [--testnet] [--peer HOST:PORT] [--max-seconds N]\n "
7375 << " " << argv0 << " --leg-c-capture [--rpc-conf PATH]\n "
74- << " " << argv0 << " --leg-c-capture-p2p [--rpc-conf PATH] [--p2p-port N]\n\n "
76+ << " " << argv0 << " --leg-c-capture-p2p [--rpc-conf PATH] [--p2p-port N]\n "
77+ << " " << argv0 << " --pool [--testnet|--regtest] [--stratum [HOST:]PORT] [--peer HOST:PORT] [--anchor N]\n\n "
7578 << " Status: M5 pool/sharechain + embedded-daemon assembly live.\n "
7679 << " The embedded daemon (coin/embedded_daemon.hpp) is the primary\n "
7780 << " work source; external BCHN-RPC stays as the fallback.\n "
@@ -583,6 +586,70 @@ int run_leg_c_capture_p2p(const std::string& conf_path, uint16_t p2p_port)
583586 return confirmed ? 0 : 1 ;
584587}
585588
589+
590+ // --pool: PRODUCTION pool run-loop -- the first non-harness c2pool-bch
591+ // entrypoint. Stands up the BCH pool node + embedded coin daemon on one shared
592+ // io_context via bch::standup_pool_run, with the won-block sink bound (dual
593+ // path: embedded P2P primary + BCHN submitblock fallback) and, when --stratum
594+ // is given, the miner-facing BCHWorkSource + core::StratumServer listening so a
595+ // genuine share-author coinbase is what gets assembled and broadcast. The
596+ // --ibd path is a read-only evidence harness; THIS path is the real node.
597+ //
598+ // Config is built WITHOUT a YAML load (matches run_ibd): no pool.yaml/coin.yaml
599+ // is required for the slice. The two embedded-daemon wire fields (P2P magic +
600+ // BCHN peer) and the sharechain PREFIX (bucket-1 isolation primitive, never
601+ // standardized) are set by hand from BCH chainparams. The external BCHN-RPC
602+ // fallback inside EmbeddedDaemon::run() is retained (external_fallback law).
603+ //
604+ // p2pool-merged-v36 surface: NONE -- run-loop bring-up + block dispatch, not
605+ // share/PPLNS/coinbase/PoW bytes. PER-COIN ISOLATION: src/impl/bch only.
606+ int run_pool (const std::string& peer_host, uint16_t peer_port, bool testnet,
607+ bool regtest, uint32_t anchor_height,
608+ const std::string& stratum_addr, uint16_t stratum_port)
609+ {
610+ boost::asio::io_context ioc;
611+
612+ bch::PoolConfig::is_testnet = testnet;
613+
614+ bch::Config config (" bch" );
615+ // Skip Config::init() (no on-disk pool.yaml/coin.yaml); set only the fields
616+ // the run-loop touches, from BCH chainparams.
617+ config.coin ()->m_testnet = testnet || regtest;
618+ config.coin ()->m_symbol = " BCH" ;
619+ config.coin ()->m_p2p .address = NetService (peer_host, peer_port);
620+ // BCH P2P network magic (pchMessageStart, BCHN chainparams.cpp): mainnet
621+ // e3e1f3e8, testnet3 f4e5f3f4, regtest dab5bffa. Wrong magic == BCHN drops
622+ // the peer with EOF right after connect.
623+ config.coin ()->m_p2p .prefix = regtest
624+ ? std::vector<std::byte>{ std::byte{0xda }, std::byte{0xb5 }, std::byte{0xbf }, std::byte{0xfa } }
625+ : (testnet
626+ ? std::vector<std::byte>{ std::byte{0xf4 }, std::byte{0xe5 }, std::byte{0xf3 }, std::byte{0xf4 } }
627+ : std::vector<std::byte>{ std::byte{0xe3 }, std::byte{0xe1 }, std::byte{0xf3 }, std::byte{0xe8 } });
628+ // Sharechain identity: BCH p2pool PREFIX namespaces the sharechain P2P
629+ // framing. standup_pool_run's Node reads pool()->m_prefix.
630+ config.pool ()->m_prefix = ParseHexBytes (bch::PoolConfig::prefix_hex ());
631+
632+ std::cout
633+ << " [pool] c2pool-bch pool run-loop"
634+ << (regtest ? " (regtest)" : (testnet ? " (testnet)" : " (mainnet)" ))
635+ << " -- BCHN peer " << peer_host << " :" << peer_port
636+ << " , cold-start anchor=" << anchor_height;
637+ if (stratum_port)
638+ std::cout << " , stratum " << stratum_addr << " :" << stratum_port;
639+ else
640+ std::cout << " , stratum DISABLED (no --stratum)" ;
641+ std::cout << " \n " ;
642+
643+ try {
644+ bch::standup_pool_run (ioc, config, anchor_height,
645+ stratum_addr, stratum_port, testnet || regtest, regtest);
646+ } catch (const std::exception& e) {
647+ std::cout << " [pool] FATAL: " << e.what () << " \n " ;
648+ return 1 ;
649+ }
650+ return 0 ;
651+ }
652+
586653} // namespace
587654
588655int main (int argc, char ** argv)
@@ -592,6 +659,11 @@ int main(int argc, char** argv)
592659 bool want_leg_c = false ;
593660 bool want_leg_c_p2p = false ;
594661 bool want_with_peer_verify = false ;
662+ bool want_pool = false ;
663+ bool regtest = false ;
664+ std::string stratum_addr = " 0.0.0.0" ;
665+ uint16_t stratum_port = 0 ; // 0 disables stratum; --stratum sets it
666+ uint32_t anchor_height = 0 ; // cold-start ABLA floor anchor
595667 uint16_t leg_c_p2p_port = 18444 ; // BCHN regtest P2P default
596668 std::string rpc_conf;
597669 bool testnet = false ;
@@ -609,6 +681,20 @@ int main(int argc, char** argv)
609681 if (std::strcmp (argv[i], " --help" ) == 0 ) want_help = true ;
610682 if (std::strcmp (argv[i], " --ibd" ) == 0 ) want_ibd = true ;
611683 if (std::strcmp (argv[i], " --with-peer-verify" ) == 0 ) want_with_peer_verify = true ;
684+ if (std::strcmp (argv[i], " --pool" ) == 0 ) want_pool = true ;
685+ if (std::strcmp (argv[i], " --regtest" ) == 0 ) { regtest = true ; testnet = true ; port = 18444 ; }
686+ if (std::strcmp (argv[i], " --anchor" ) == 0 && i + 1 < argc)
687+ anchor_height = static_cast <uint32_t >(std::stoul (argv[++i]));
688+ if (std::strcmp (argv[i], " --stratum" ) == 0 && i + 1 < argc) {
689+ std::string sp = argv[++i];
690+ const auto c = sp.rfind (char (58 )); // ASCII colon
691+ if (c != std::string::npos) {
692+ stratum_addr = sp.substr (0 , c);
693+ stratum_port = static_cast <uint16_t >(std::stoul (sp.substr (c + 1 )));
694+ } else {
695+ stratum_port = static_cast <uint16_t >(std::stoul (sp));
696+ }
697+ }
612698 if (std::strcmp (argv[i], " --leg-c-capture" ) == 0 ) want_leg_c = true ;
613699 if (std::strcmp (argv[i], " --leg-c-capture-p2p" ) == 0 ) want_leg_c_p2p = true ;
614700 if (std::strcmp (argv[i], " --p2p-port" ) == 0 && i + 1 < argc)
@@ -651,6 +737,9 @@ int main(int argc, char** argv)
651737 return run_leg_c_capture (rpc_conf);
652738 }
653739
740+ if (want_pool)
741+ return run_pool (host, port, testnet, regtest, anchor_height, stratum_addr, stratum_port);
742+
654743 if (want_with_peer_verify)
655744 return run_with_peer_verify (host, port, testnet, max_seconds);
656745
0 commit comments