Skip to content

Commit 0933344

Browse files
committed
Start Template Provider with -sv2
1 parent fd26e38 commit 0933344

File tree

5 files changed

+92
-1
lines changed

5 files changed

+92
-1
lines changed

src/CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,8 +304,15 @@ target_link_libraries(bitcoin_node
304304
libevent::extra
305305
$<TARGET_NAME_IF_EXISTS:libevent::pthreads>
306306
$<TARGET_NAME_IF_EXISTS:USDT::headers>
307+
$<TARGET_NAME_IF_EXISTS:bitcoin_sv2>
307308
)
308309

310+
if(WITH_SV2)
311+
target_compile_definitions(bitcoin_node
312+
PUBLIC
313+
WITH_SV2=1
314+
)
315+
endif()
309316

310317
# Bitcoin Core bitcoind.
311318
if(BUILD_DAEMON)

src/init.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@
5454
#include <node/mempool_persist_args.h>
5555
#include <node/miner.h>
5656
#include <node/peerman_args.h>
57+
#ifdef WITH_SV2
58+
#include <sv2/template_provider.h>
59+
#endif
5760
#include <policy/feerate.h>
5861
#include <policy/fees.h>
5962
#include <policy/fees_args.h>
@@ -268,6 +271,11 @@ void Interrupt(NodeContext& node)
268271
InterruptRPC();
269272
InterruptREST();
270273
InterruptTorControl();
274+
#ifdef WITH_SV2
275+
if (node.sv2_template_provider) {
276+
node.sv2_template_provider->Interrupt();
277+
}
278+
#endif
271279
InterruptMapPort();
272280
if (node.connman)
273281
node.connman->Interrupt();
@@ -307,6 +315,11 @@ void Shutdown(NodeContext& node)
307315

308316
StopTorControl();
309317

318+
#ifdef WITH_SV2
319+
// Stop Template Provider
320+
if (node.sv2_template_provider) node.sv2_template_provider->StopThreads();
321+
#endif
322+
310323
if (node.background_init_thread.joinable()) node.background_init_thread.join();
311324
// After everything has been shut down, but before things get flushed, stop the
312325
// the scheduler. After this point, SyncWithValidationInterfaceQueue() should not be called anymore
@@ -320,6 +333,9 @@ void Shutdown(NodeContext& node)
320333
node.banman.reset();
321334
node.addrman.reset();
322335
node.netgroupman.reset();
336+
#ifdef WITH_SV2
337+
node.sv2_template_provider.reset();
338+
#endif
323339

324340
if (node.mempool && node.mempool->GetLoadTried() && ShouldPersistMempool(*node.args)) {
325341
DumpMempool(*node.mempool, MempoolPath(*node.args));
@@ -648,6 +664,11 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
648664
argsman.AddArg("-blockmaxweight=<n>", strprintf("Set maximum BIP141 block weight (default: %d)", DEFAULT_BLOCK_MAX_WEIGHT), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
649665
argsman.AddArg("-blockmintxfee=<amt>", strprintf("Set lowest fee rate (in %s/kvB) for transactions to be included in block creation. (default: %s)", CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
650666
argsman.AddArg("-blockversion=<n>", "Override block version to test forking scenarios", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::BLOCK_CREATION);
667+
#ifdef WITH_SV2
668+
argsman.AddArg("-sv2", "Bitcoind will act as a Stratum v2 Template Provider (default: false)", ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
669+
argsman.AddArg("-sv2interval", strprintf("Template Provider block template update interval (default: %d seconds)", Sv2TemplateProviderOptions().fee_check_interval.count()), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
670+
argsman.AddArg("-sv2feedelta", strprintf("Minimum fee delta for Template Provider to send update upstream (default: %d sat)", uint64_t(Sv2TemplateProviderOptions().fee_delta)), ArgsManager::ALLOW_ANY, OptionsCategory::BLOCK_CREATION);
671+
#endif
651672

652673
argsman.AddArg("-rest", strprintf("Accept public REST requests (default: %u)", DEFAULT_REST_ENABLE), ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
653674
argsman.AddArg("-rpcallowip=<ip>", "Allow JSON-RPC connections from specified source. Valid values for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0), a network/CIDR (e.g. 1.2.3.4/24), all ipv4 (0.0.0.0/0), or all ipv6 (::/0). This option can be specified multiple times", ArgsManager::ALLOW_ANY, OptionsCategory::RPC);
@@ -669,6 +690,11 @@ void SetupServerArgs(ArgsManager& argsman, bool can_listen_ipc)
669690
argsman.AddArg("-ipcbind=<address>", "Bind to Unix socket address and listen for incoming connections. Valid address values are \"unix\" to listen on the default path, <datadir>/node.sock, or \"unix:/custom/path\" to specify a custom path. Can be specified multiple times to listen on multiple paths. Default behavior is not to listen on any path. If relative paths are specified, they are interpreted relative to the network data directory. If paths include any parent directory components and the parent directories do not exist, they will be created.", ArgsManager::ALLOW_ANY, OptionsCategory::IPC);
670691
}
671692

693+
#ifdef WITH_SV2
694+
argsman.AddArg("-sv2bind=<addr>[:<port>]", strprintf("Bind to given address and always listen on it (default: 127.0.0.1). Use [host]:port notation for IPv6."), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
695+
argsman.AddArg("-sv2port=<port>", strprintf("Listen for Stratum v2 connections on <port> (default: %u, testnet: %u, signet: %u, regtest: %u)", defaultBaseParams->Sv2Port(), testnetBaseParams->Sv2Port(), signetBaseParams->Sv2Port(), regtestBaseParams->Sv2Port()), ArgsManager::ALLOW_ANY | ArgsManager::NETWORK_ONLY, OptionsCategory::CONNECTION);
696+
#endif
697+
672698
#if HAVE_DECL_FORK
673699
argsman.AddArg("-daemon", strprintf("Run in the background as a daemon and accept commands (default: %d)", DEFAULT_DAEMON), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
674700
argsman.AddArg("-daemonwait", strprintf("Wait for initialization to be finished before exiting. This implies -daemon (default: %d)", DEFAULT_DAEMONWAIT), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
@@ -1142,6 +1168,9 @@ bool CheckHostPortOptions(const ArgsManager& args) {
11421168
{"-onion", true},
11431169
{"-proxy", true},
11441170
{"-rpcbind", false},
1171+
#ifdef WITH_SV2
1172+
{"-sv2bind", false},
1173+
#endif
11451174
{"-torcontrol", false},
11461175
{"-whitebind", false},
11471176
{"-zmqpubhashblock", true},
@@ -1978,6 +2007,49 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info)
19782007
return false;
19792008
}
19802009

2010+
#ifdef WITH_SV2
2011+
if (args.GetBoolArg("-sv2", false)) {
2012+
assert(!node.sv2_template_provider);
2013+
assert(node.mining);
2014+
2015+
Sv2TemplateProviderOptions options{};
2016+
2017+
node.sv2_template_provider = std::make_unique<Sv2TemplateProvider>(*node.mining);
2018+
2019+
const std::string sv2_port_arg = args.GetArg("-sv2port", "");
2020+
2021+
if (sv2_port_arg.empty()) {
2022+
options.port = BaseParams().Sv2Port();
2023+
} else {
2024+
if (!ParseUInt16(sv2_port_arg, &options.port) || options.port == 0) {
2025+
return InitError(InvalidPortErrMsg("sv2port", sv2_port_arg));
2026+
}
2027+
}
2028+
2029+
if (gArgs.IsArgSet("-sv2bind")) { // Specific bind address
2030+
std::optional<std::string> sv2_bind{gArgs.GetArg("-sv2bind")};
2031+
if (sv2_bind) {
2032+
if (!SplitHostPort(sv2_bind.value(), options.port, options.host)) {
2033+
throw std::runtime_error(strprintf("Invalid port %d", options.port));
2034+
}
2035+
}
2036+
}
2037+
2038+
options.fee_delta = gArgs.GetIntArg("-sv2feedelta", Sv2TemplateProviderOptions().fee_delta);
2039+
2040+
if (gArgs.IsArgSet("-sv2interval")) {
2041+
if (args.GetIntArg("-sv2interval", 0) < 1) {
2042+
return InitError(Untranslated("-sv2interval must be at least one second"));
2043+
}
2044+
options.fee_check_interval = std::chrono::seconds(gArgs.GetIntArg("-sv2interval", 0));
2045+
}
2046+
2047+
if (!node.sv2_template_provider->Start(options)) {
2048+
return InitError(_("Unable to start Stratum v2 Template Provider"));
2049+
}
2050+
}
2051+
#endif
2052+
19812053
// ********************************************************* Step 13: finished
19822054

19832055
// At this point, the RPC is "started", but still in warmup, which means it

src/node/context.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
#include <node/warnings.h>
1818
#include <policy/fees.h>
1919
#include <scheduler.h>
20+
#ifdef WITH_SV2
21+
#include <sv2/template_provider.h>
22+
#endif
2023
#include <txmempool.h>
2124
#include <validation.h>
2225
#include <validationinterface.h>

src/node/context.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ class ChainstateManager;
2525
class ECC_Context;
2626
class NetGroupManager;
2727
class PeerManager;
28+
#ifdef WITH_SV2
2829
class Sv2TemplateProvider;
30+
#endif
2931
namespace interfaces {
3032
class Chain;
3133
class ChainClient;
@@ -40,6 +42,11 @@ namespace util {
4042
class SignalInterrupt;
4143
}
4244

45+
#ifndef WITH_SV2
46+
// Dummy
47+
class Sv2TemplateProvider {};
48+
#endif
49+
4350
namespace node {
4451
class KernelNotifications;
4552
class Warnings;
@@ -72,6 +79,7 @@ struct NodeContext {
7279
std::unique_ptr<PeerManager> peerman;
7380
std::unique_ptr<ChainstateManager> chainman;
7481
std::unique_ptr<BanMan> banman;
82+
std::unique_ptr<Sv2TemplateProvider> sv2_template_provider;
7583
ArgsManager* args{nullptr}; // Currently a raw pointer because the memory is not managed by this struct
7684
std::vector<BaseIndex*> indexes; // raw pointers because memory is not managed by this struct
7785
std::unique_ptr<interfaces::Chain> chain;

src/test/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,8 @@ if(WITH_SV2)
184184
sv2_messages_tests.cpp
185185
sv2_template_provider_tests.cpp
186186
)
187-
target_link_libraries(test_bitcoin bitcoin_sv2)
187+
# target_link_libraries is not needed here, because bitcoin_sv2 is included
188+
# by bitcoin_node below
188189
endif()
189190

190191
function(add_boost_test source_file)

0 commit comments

Comments
 (0)