mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-06-15 00:59:38 +02:00
Merge bitcoin/bitcoin#35335: Make deployment configuration available outside of regtest in unit tests
801e3bfe38chainparams: add overloads for RegTest and SigNet with no options (Antoine Poinsot)4995c00a9cchainparams: make deployment configuration available on all test networks (Antoine Poinsot)df7ed5f355chainparams: encapsulate deployment configuration logic (Antoine Poinsot) Pull request description: It's sometimes useful to test a deployment on other networks than regtest. This may be e.g. because regtest lacks a property relevant for the test, or simply because the test aims to be portable while regtest is Bitcoin Core specific. This PR makes it possible to set the `-vbparams` and `-testactivationheight` options on any network in unit tests, and on any **test** network as a startup option. This is preparatory work for a BIP 54 implementation, but may be useful separately. ACKs for top commit: edilmedeiros: utACK801e3bfe38achow101: ACK801e3bfe38sedited: ACK801e3bfe38instagibbs: ACK801e3bfe38Tree-SHA512: 10649dc9bbc70a830bb0c4b1c965de5bf2e6be1a6c2832bdf11e9248dacb4a1f60421b410d0284213e88de6c54218252ae5de423b4c6e659d10bab1cbe7e7e87
This commit is contained in:
@@ -23,29 +23,8 @@
|
||||
|
||||
using util::SplitString;
|
||||
|
||||
void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options)
|
||||
static void HandleDeploymentArgs(const ArgsManager& args, CChainParams::DeploymentOptions& options)
|
||||
{
|
||||
if (!args.GetArgs("-signetseednode").empty()) {
|
||||
options.seeds.emplace(args.GetArgs("-signetseednode"));
|
||||
}
|
||||
if (!args.GetArgs("-signetchallenge").empty()) {
|
||||
const auto signet_challenge = args.GetArgs("-signetchallenge");
|
||||
if (signet_challenge.size() != 1) {
|
||||
throw std::runtime_error("-signetchallenge cannot be multiple values.");
|
||||
}
|
||||
const auto val{TryParseHex<uint8_t>(signet_challenge[0])};
|
||||
if (!val) {
|
||||
throw std::runtime_error(strprintf("-signetchallenge must be hex, not '%s'.", signet_challenge[0]));
|
||||
}
|
||||
options.challenge.emplace(*val);
|
||||
}
|
||||
}
|
||||
|
||||
void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options)
|
||||
{
|
||||
if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value;
|
||||
if (HasTestOption(args, "bip94")) options.enforce_bip94 = true;
|
||||
|
||||
for (const std::string& arg : args.GetArgs("-testactivationheight")) {
|
||||
const auto found{arg.find('@')};
|
||||
if (found == std::string::npos) {
|
||||
@@ -107,6 +86,43 @@ void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& opti
|
||||
}
|
||||
}
|
||||
|
||||
void ReadMainNetArgs(const ArgsManager& args, CChainParams::MainNetOptions& options)
|
||||
{
|
||||
HandleDeploymentArgs(args, options.dep_opts);
|
||||
}
|
||||
|
||||
void ReadTestNetArgs(const ArgsManager& args, CChainParams::TestNetOptions& options)
|
||||
{
|
||||
HandleDeploymentArgs(args, options.dep_opts);
|
||||
}
|
||||
|
||||
void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options)
|
||||
{
|
||||
if (!args.GetArgs("-signetseednode").empty()) {
|
||||
options.seeds.emplace(args.GetArgs("-signetseednode"));
|
||||
}
|
||||
if (!args.GetArgs("-signetchallenge").empty()) {
|
||||
const auto signet_challenge = args.GetArgs("-signetchallenge");
|
||||
if (signet_challenge.size() != 1) {
|
||||
throw std::runtime_error("-signetchallenge cannot be multiple values.");
|
||||
}
|
||||
const auto val{TryParseHex<uint8_t>(signet_challenge[0])};
|
||||
if (!val) {
|
||||
throw std::runtime_error(strprintf("-signetchallenge must be hex, not '%s'.", signet_challenge[0]));
|
||||
}
|
||||
options.challenge.emplace(*val);
|
||||
}
|
||||
HandleDeploymentArgs(args, options.dep_opts);
|
||||
}
|
||||
|
||||
void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options)
|
||||
{
|
||||
if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value;
|
||||
if (HasTestOption(args, "bip94")) options.enforce_bip94 = true;
|
||||
|
||||
HandleDeploymentArgs(args, options.dep_opts);
|
||||
}
|
||||
|
||||
static std::unique_ptr<const CChainParams> globalChainParams;
|
||||
|
||||
const CChainParams &Params() {
|
||||
@@ -117,12 +133,21 @@ const CChainParams &Params() {
|
||||
std::unique_ptr<const CChainParams> CreateChainParams(const ArgsManager& args, const ChainType chain)
|
||||
{
|
||||
switch (chain) {
|
||||
case ChainType::MAIN:
|
||||
return CChainParams::Main();
|
||||
case ChainType::TESTNET:
|
||||
return CChainParams::TestNet();
|
||||
case ChainType::TESTNET4:
|
||||
return CChainParams::TestNet4();
|
||||
case ChainType::MAIN: {
|
||||
auto opts = CChainParams::MainNetOptions{};
|
||||
ReadMainNetArgs(args, opts);
|
||||
return CChainParams::Main(opts);
|
||||
}
|
||||
case ChainType::TESTNET: {
|
||||
auto opts = CChainParams::TestNetOptions{};
|
||||
ReadTestNetArgs(args, opts);
|
||||
return CChainParams::TestNet(opts);
|
||||
}
|
||||
case ChainType::TESTNET4: {
|
||||
auto opts = CChainParams::TestNetOptions{};
|
||||
ReadTestNetArgs(args, opts);
|
||||
return CChainParams::TestNet4(opts);
|
||||
}
|
||||
case ChainType::SIGNET: {
|
||||
auto opts = CChainParams::SigNetOptions{};
|
||||
ReadSigNetArgs(args, opts);
|
||||
|
||||
@@ -16,10 +16,10 @@ void SetupChainParamsBaseOptions(ArgsManager& argsman)
|
||||
argsman.AddArg("-chain=<chain>", "Use the chain <chain> (default: main). Allowed values: " LIST_CHAIN_NAMES, ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-regtest", "Enter regression test mode, which uses a special chain in which blocks can be solved instantly. "
|
||||
"This is intended for regression testing tools and app development. Equivalent to -chain=regtest.", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (segwit, bip34, dersig, cltv, csv). (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||
argsman.AddArg("-testactivationheight=name@height.", "Set the activation height of 'name' (segwit, bip34, dersig, cltv, csv). (test-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST);
|
||||
argsman.AddArg("-testnet", "Use the testnet3 chain. Equivalent to -chain=test. Support for testnet3 is deprecated and will be removed in an upcoming release. Consider moving to testnet4 now by using -testnet4.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-testnet4", "Use the testnet4 chain. Equivalent to -chain=testnet4.", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-vbparams=deployment:start:end[:min_activation_height]", "Use given start/end times and min_activation_height for specified version bits deployment (regtest-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-vbparams=deployment:start:end[:min_activation_height]", "Use given start/end times and min_activation_height for specified version bits deployment (test-only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-signet", "Use the signet chain. Equivalent to -chain=signet. Note that the network is defined by the -signetchallenge parameter", ArgsManager::ALLOW_ANY, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-signetchallenge", "Blocks must satisfy the given script to be considered valid (only for signet networks; defaults to the global default signet test network challenge)", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::CHAINPARAMS);
|
||||
argsman.AddArg("-signetseednode", "Specify a seed node for the signet network, in the hostname[:port] format, e.g. sig.net:1234 (may be used multiple times to specify multiple seed nodes; defaults to the global default signet test network seed node(s))", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::CHAINPARAMS);
|
||||
|
||||
10
src/init.cpp
10
src/init.cpp
@@ -1125,6 +1125,16 @@ bool AppInitParameterInteraction(const ArgsManager& args)
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent setting deployment parameters on mainnet.
|
||||
if (chainparams.GetChainType() == ChainType::MAIN) {
|
||||
if (args.IsArgSet("-testactivationheight")) {
|
||||
return InitError(_("The -testactivationheight option may not be used on mainnet."));
|
||||
}
|
||||
if (args.IsArgSet("-vbparams")) {
|
||||
return InitError(_("The -vbparams option may not be used on mainnet."));
|
||||
}
|
||||
}
|
||||
|
||||
// Also report errors from parsing before daemonization
|
||||
{
|
||||
kernel::Notifications notifications{};
|
||||
|
||||
@@ -813,10 +813,10 @@ btck_ChainParameters* btck_chain_parameters_create(const btck_ChainType chain_ty
|
||||
return btck_ChainParameters::ref(const_cast<CChainParams*>(CChainParams::TestNet4().release()));
|
||||
}
|
||||
case btck_ChainType_SIGNET: {
|
||||
return btck_ChainParameters::ref(const_cast<CChainParams*>(CChainParams::SigNet({}).release()));
|
||||
return btck_ChainParameters::ref(const_cast<CChainParams*>(CChainParams::SigNet().release()));
|
||||
}
|
||||
case btck_ChainType_REGTEST: {
|
||||
return btck_ChainParameters::ref(const_cast<CChainParams*>(CChainParams::RegTest({}).release()));
|
||||
return btck_ChainParameters::ref(const_cast<CChainParams*>(CChainParams::RegTest().release()));
|
||||
}
|
||||
}
|
||||
assert(false);
|
||||
|
||||
@@ -73,12 +73,41 @@ static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits
|
||||
return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward);
|
||||
}
|
||||
|
||||
void CChainParams::ApplyDeploymentOptions(const DeploymentOptions& opts)
|
||||
{
|
||||
for (const auto& [dep, height] : opts.activation_heights) {
|
||||
switch (dep) {
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_SEGWIT:
|
||||
consensus.SegwitHeight = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_HEIGHTINCB:
|
||||
consensus.BIP34Height = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_DERSIG:
|
||||
consensus.BIP66Height = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_CLTV:
|
||||
consensus.BIP65Height = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_CSV:
|
||||
consensus.CSVHeight = int{height};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [deployment_pos, version_bits_params] : opts.version_bits_parameters) {
|
||||
consensus.vDeployments[deployment_pos].nStartTime = version_bits_params.start_time;
|
||||
consensus.vDeployments[deployment_pos].nTimeout = version_bits_params.timeout;
|
||||
consensus.vDeployments[deployment_pos].min_activation_height = version_bits_params.min_activation_height;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main network on which people trade goods and services.
|
||||
*/
|
||||
class CMainParams : public CChainParams {
|
||||
public:
|
||||
CMainParams() {
|
||||
CMainParams(const MainNetOptions& opts) {
|
||||
m_chain_type = ChainType::MAIN;
|
||||
consensus.signet_blocks = false;
|
||||
consensus.signet_challenge.clear();
|
||||
@@ -107,6 +136,8 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1815; // 90%
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
|
||||
|
||||
ApplyDeploymentOptions(opts.dep_opts);
|
||||
|
||||
consensus.nMinimumChainWork = uint256{"0000000000000000000000000000000000000001128750f82f4c366153a3a030"};
|
||||
consensus.defaultAssumeValid = uint256{"00000000000000000000ccebd6d74d9194d8dcdc1d177c478e094bfad51ba5ac"}; // 938343
|
||||
|
||||
@@ -203,7 +234,7 @@ public:
|
||||
*/
|
||||
class CTestNetParams : public CChainParams {
|
||||
public:
|
||||
CTestNetParams() {
|
||||
CTestNetParams(const TestNetOptions& opts) {
|
||||
m_chain_type = ChainType::TESTNET;
|
||||
consensus.signet_blocks = false;
|
||||
consensus.signet_challenge.clear();
|
||||
@@ -230,6 +261,8 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1512; // 75%
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
|
||||
|
||||
ApplyDeploymentOptions(opts.dep_opts);
|
||||
|
||||
consensus.nMinimumChainWork = uint256{"0000000000000000000000000000000000000000000017dde1c649f3708d14b6"};
|
||||
consensus.defaultAssumeValid = uint256{"000000007a61e4230b28ac5cb6b5e5a0130de37ac1faf2f8987d2fa6505b67f4"}; // 4842348
|
||||
|
||||
@@ -304,7 +337,7 @@ public:
|
||||
*/
|
||||
class CTestNet4Params : public CChainParams {
|
||||
public:
|
||||
CTestNet4Params() {
|
||||
CTestNet4Params(const TestNetOptions& opts) {
|
||||
m_chain_type = ChainType::TESTNET4;
|
||||
consensus.signet_blocks = false;
|
||||
consensus.signet_challenge.clear();
|
||||
@@ -330,6 +363,8 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1512; // 75%
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
|
||||
|
||||
ApplyDeploymentOptions(opts.dep_opts);
|
||||
|
||||
consensus.nMinimumChainWork = uint256{"0000000000000000000000000000000000000000000009a0fe15d0177d086304"};
|
||||
consensus.defaultAssumeValid = uint256{"0000000002368b1e4ee27e2e85676ae6f9f9e69579b29093e9a82c170bf7cf8a"}; // 123613
|
||||
|
||||
@@ -473,6 +508,8 @@ public:
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].threshold = 1815; // 90%
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].period = 2016;
|
||||
|
||||
ApplyDeploymentOptions(options.dep_opts);
|
||||
|
||||
// message start is defined as the first 4 bytes of the sha256d of the block script
|
||||
HashWriter h{};
|
||||
h << consensus.signet_challenge;
|
||||
@@ -567,31 +604,7 @@ public:
|
||||
m_assumed_blockchain_size = 0;
|
||||
m_assumed_chain_state_size = 0;
|
||||
|
||||
for (const auto& [dep, height] : opts.activation_heights) {
|
||||
switch (dep) {
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_SEGWIT:
|
||||
consensus.SegwitHeight = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_HEIGHTINCB:
|
||||
consensus.BIP34Height = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_DERSIG:
|
||||
consensus.BIP66Height = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_CLTV:
|
||||
consensus.BIP65Height = int{height};
|
||||
break;
|
||||
case Consensus::BuriedDeployment::DEPLOYMENT_CSV:
|
||||
consensus.CSVHeight = int{height};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [deployment_pos, version_bits_params] : opts.version_bits_parameters) {
|
||||
consensus.vDeployments[deployment_pos].nStartTime = version_bits_params.start_time;
|
||||
consensus.vDeployments[deployment_pos].nTimeout = version_bits_params.timeout;
|
||||
consensus.vDeployments[deployment_pos].min_activation_height = version_bits_params.min_activation_height;
|
||||
}
|
||||
ApplyDeploymentOptions(opts.dep_opts);
|
||||
|
||||
genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN);
|
||||
consensus.hashGenesisBlock = genesis.GetHash();
|
||||
@@ -660,19 +673,19 @@ std::unique_ptr<const CChainParams> CChainParams::RegTest(const RegTestOptions&
|
||||
return std::make_unique<const CRegTestParams>(options);
|
||||
}
|
||||
|
||||
std::unique_ptr<const CChainParams> CChainParams::Main()
|
||||
std::unique_ptr<const CChainParams> CChainParams::Main(const MainNetOptions& options)
|
||||
{
|
||||
return std::make_unique<const CMainParams>();
|
||||
return std::make_unique<const CMainParams>(options);
|
||||
}
|
||||
|
||||
std::unique_ptr<const CChainParams> CChainParams::TestNet()
|
||||
std::unique_ptr<const CChainParams> CChainParams::TestNet(const TestNetOptions& options)
|
||||
{
|
||||
return std::make_unique<const CTestNetParams>();
|
||||
return std::make_unique<const CTestNetParams>(options);
|
||||
}
|
||||
|
||||
std::unique_ptr<const CChainParams> CChainParams::TestNet4()
|
||||
std::unique_ptr<const CChainParams> CChainParams::TestNet4(const TestNetOptions& options)
|
||||
{
|
||||
return std::make_unique<const CTestNet4Params>();
|
||||
return std::make_unique<const CTestNet4Params>(options);
|
||||
}
|
||||
|
||||
std::vector<int> CChainParams::GetAvailableSnapshotHeights() const
|
||||
@@ -691,8 +704,8 @@ std::optional<ChainType> GetNetworkForMagic(const MessageStartChars& message)
|
||||
const auto mainnet_msg = CChainParams::Main()->MessageStart();
|
||||
const auto testnet_msg = CChainParams::TestNet()->MessageStart();
|
||||
const auto testnet4_msg = CChainParams::TestNet4()->MessageStart();
|
||||
const auto regtest_msg = CChainParams::RegTest({})->MessageStart();
|
||||
const auto signet_msg = CChainParams::SigNet({})->MessageStart();
|
||||
const auto regtest_msg = CChainParams::RegTest()->MessageStart();
|
||||
const auto signet_msg = CChainParams::SigNet()->MessageStart();
|
||||
|
||||
if (std::ranges::equal(message, mainnet_msg)) {
|
||||
return ChainType::MAIN;
|
||||
|
||||
@@ -127,14 +127,6 @@ public:
|
||||
|
||||
const ChainTxData& TxData() const { return chainTxData; }
|
||||
|
||||
/**
|
||||
* SigNetOptions holds configurations for creating a signet CChainParams.
|
||||
*/
|
||||
struct SigNetOptions {
|
||||
std::optional<std::vector<uint8_t>> challenge{};
|
||||
std::optional<std::vector<std::string>> seeds{};
|
||||
};
|
||||
|
||||
/**
|
||||
* VersionBitsParameters holds activation parameters
|
||||
*/
|
||||
@@ -144,21 +136,47 @@ public:
|
||||
int min_activation_height;
|
||||
};
|
||||
|
||||
struct DeploymentOptions {
|
||||
std::unordered_map<Consensus::DeploymentPos, VersionBitsParameters> version_bits_parameters{};
|
||||
std::unordered_map<Consensus::BuriedDeployment, int> activation_heights{};
|
||||
};
|
||||
|
||||
/**
|
||||
* SigNetOptions holds configurations for creating a signet CChainParams.
|
||||
*/
|
||||
struct SigNetOptions {
|
||||
DeploymentOptions dep_opts{};
|
||||
std::optional<std::vector<uint8_t>> challenge{};
|
||||
std::optional<std::vector<std::string>> seeds{};
|
||||
};
|
||||
|
||||
/**
|
||||
* RegTestOptions holds configurations for creating a regtest CChainParams.
|
||||
*/
|
||||
struct RegTestOptions {
|
||||
std::unordered_map<Consensus::DeploymentPos, VersionBitsParameters> version_bits_parameters{};
|
||||
std::unordered_map<Consensus::BuriedDeployment, int> activation_heights{};
|
||||
DeploymentOptions dep_opts{};
|
||||
bool fastprune{false};
|
||||
bool enforce_bip94{false};
|
||||
};
|
||||
|
||||
struct MainNetOptions {
|
||||
DeploymentOptions dep_opts{};
|
||||
};
|
||||
|
||||
struct TestNetOptions {
|
||||
DeploymentOptions dep_opts{};
|
||||
};
|
||||
|
||||
static std::unique_ptr<const CChainParams> RegTest(const RegTestOptions& options);
|
||||
static std::unique_ptr<const CChainParams> RegTest() { const RegTestOptions opts{}; return RegTest(opts); }
|
||||
static std::unique_ptr<const CChainParams> SigNet(const SigNetOptions& options);
|
||||
static std::unique_ptr<const CChainParams> Main();
|
||||
static std::unique_ptr<const CChainParams> TestNet();
|
||||
static std::unique_ptr<const CChainParams> TestNet4();
|
||||
static std::unique_ptr<const CChainParams> SigNet() { const SigNetOptions opts{}; return SigNet(opts); }
|
||||
static std::unique_ptr<const CChainParams> Main(const MainNetOptions& options);
|
||||
static std::unique_ptr<const CChainParams> Main() { const MainNetOptions opts{}; return Main(opts); }
|
||||
static std::unique_ptr<const CChainParams> TestNet(const TestNetOptions& options);
|
||||
static std::unique_ptr<const CChainParams> TestNet() { const TestNetOptions opts{}; return TestNet(opts); }
|
||||
static std::unique_ptr<const CChainParams> TestNet4(const TestNetOptions& options);
|
||||
static std::unique_ptr<const CChainParams> TestNet4() { const TestNetOptions opts{}; return TestNet4(opts); }
|
||||
|
||||
protected:
|
||||
CChainParams() = default;
|
||||
@@ -180,6 +198,8 @@ protected:
|
||||
std::vector<AssumeutxoData> m_assumeutxo_data;
|
||||
ChainTxData chainTxData;
|
||||
HeadersSyncParams m_headers_sync_params;
|
||||
|
||||
void ApplyDeploymentOptions(const DeploymentOptions& opts);
|
||||
};
|
||||
|
||||
std::optional<ChainType> GetNetworkForMagic(const MessageStartChars& pchMessageStart);
|
||||
|
||||
Reference in New Issue
Block a user