From 76cd4e7c96242398172989609f1b9a8843c404b4 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Wed, 9 Mar 2022 00:13:36 -0500 Subject: [PATCH 1/6] Decouple SigNetChainParams from ArgsManager SigNet chain params can now be initialized by configuring a SigNetOptions struct, or with ArgsManager. This offers an interface for creating SigNetChainParams without a gArgs object. --- src/chainparams.cpp | 39 ++++++++++++++++++++++++++------------- src/chainparams.h | 9 +++++++++ 2 files changed, 35 insertions(+), 13 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 19b5c332f4c26..12b5a788b463e 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -277,11 +277,12 @@ class CTestNetParams : public CChainParams { */ class SigNetParams : public CChainParams { public: - explicit SigNetParams(const ArgsManager& args) { + explicit SigNetParams(const SigNetOptions& options) + { std::vector bin; vSeeds.clear(); - if (!args.IsArgSet("-signetchallenge")) { + if (!options.challenge) { bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae"); vSeeds.emplace_back("seed.signet.bitcoin.sprovoost.nl."); @@ -300,12 +301,7 @@ class SigNetParams : public CChainParams { .dTxRate = 0.02336701143027275, }; } else { - const auto signet_challenge = args.GetArgs("-signetchallenge"); - if (signet_challenge.size() != 1) { - throw std::runtime_error(strprintf("%s: -signetchallenge cannot be multiple values.", __func__)); - } - bin = ParseHex(signet_challenge[0]); - + bin = *options.challenge; consensus.nMinimumChainWork = uint256{}; consensus.defaultAssumeValid = uint256{}; m_assumed_blockchain_size = 0; @@ -315,11 +311,11 @@ class SigNetParams : public CChainParams { 0, 0, }; - LogPrintf("Signet with challenge %s\n", signet_challenge[0]); + LogPrintf("Signet with challenge %s\n", HexStr(bin)); } - if (args.IsArgSet("-signetseednode")) { - vSeeds = args.GetArgs("-signetseednode"); + if (options.seeds) { + vSeeds = *options.seeds; } strNetworkID = CBaseChainParams::SIGNET; @@ -382,11 +378,26 @@ class SigNetParams : public CChainParams { } }; +void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options) +{ + if (args.IsArgSet("-signetseednode")) { + options.seeds.emplace(args.GetArgs("-signetseednode")); + } + if (args.IsArgSet("-signetchallenge")) { + const auto signet_challenge = args.GetArgs("-signetchallenge"); + if (signet_challenge.size() != 1) { + throw std::runtime_error(strprintf("%s: -signetchallenge cannot be multiple values.", __func__)); + } + options.challenge.emplace(ParseHex(signet_challenge[0])); + } +} + /** * Regression test: intended for private networks only. Has minimal difficulty to ensure that * blocks can be found instantly. */ -class CRegTestParams : public CChainParams { +class CRegTestParams : public CChainParams +{ public: explicit CRegTestParams(const ArgsManager& args) { strNetworkID = CBaseChainParams::REGTEST; @@ -570,7 +581,9 @@ std::unique_ptr CreateChainParams(const ArgsManager& args, c } else if (chain == CBaseChainParams::TESTNET) { return std::unique_ptr(new CTestNetParams()); } else if (chain == CBaseChainParams::SIGNET) { - return std::unique_ptr(new SigNetParams(args)); + auto opts = CChainParams::SigNetOptions{}; + ReadSigNetArgs(args, opts); + return std::make_unique(opts); } else if (chain == CBaseChainParams::REGTEST) { return std::unique_ptr(new CRegTestParams(args)); } diff --git a/src/chainparams.h b/src/chainparams.h index 66592ffddad06..2f6f3f0907e33 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -122,6 +122,15 @@ class CChainParams const MapAssumeutxo& Assumeutxo() const { return m_assumeutxo_data; } const ChainTxData& TxData() const { return chainTxData; } + + /** + * SigNetOptions holds configurations for creating a signet CChainParams. + */ + struct SigNetOptions { + std::optional> challenge{}; + std::optional> seeds{}; + }; + protected: CChainParams() {} From 84b85786f0f5cb23cc257a4464ae345e1d372313 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Wed, 9 Mar 2022 16:11:39 -0500 Subject: [PATCH 2/6] Decouple RegTestChainParams from ArgsManager RegTest chain params can now be initialized by configuring a RegTestOptions struct, or with ArgsManager. This offers an interface for creating RegTestChainParams without a gArgs object. --- src/chainparams.cpp | 78 ++++++++++++++++++++++++++---------------- src/chainparams.h | 20 +++++++++++ src/deploymentinfo.cpp | 18 ++++++++++ src/deploymentinfo.h | 3 ++ 4 files changed, 89 insertions(+), 30 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 12b5a788b463e..e4a5a489a2f5a 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -399,7 +399,8 @@ void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& option class CRegTestParams : public CChainParams { public: - explicit CRegTestParams(const ArgsManager& args) { + explicit CRegTestParams(const RegTestOptions& opts) + { strNetworkID = CBaseChainParams::REGTEST; consensus.signet_blocks = false; consensus.signet_challenge.clear(); @@ -437,11 +438,33 @@ class CRegTestParams : public CChainParams pchMessageStart[2] = 0xb5; pchMessageStart[3] = 0xda; nDefaultPort = 18444; - nPruneAfterHeight = args.GetBoolArg("-fastprune", false) ? 100 : 1000; + nPruneAfterHeight = opts.fastprune ? 100 : 1000; m_assumed_blockchain_size = 0; m_assumed_chain_state_size = 0; - UpdateActivationParametersFromArgs(args); + 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) { + UpdateVersionBitsParameters(deployment_pos, version_bits_params.start_time, version_bits_params.timeout, version_bits_params.min_activation_height); + } genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); consensus.hashGenesisBlock = genesis.GetHash(); @@ -498,41 +521,31 @@ class CRegTestParams : public CChainParams consensus.vDeployments[d].nTimeout = nTimeout; consensus.vDeployments[d].min_activation_height = min_activation_height; } - void UpdateActivationParametersFromArgs(const ArgsManager& args); }; -static void MaybeUpdateHeights(const ArgsManager& args, Consensus::Params& consensus) +void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options) { + if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value; + for (const std::string& arg : args.GetArgs("-testactivationheight")) { const auto found{arg.find('@')}; if (found == std::string::npos) { throw std::runtime_error(strprintf("Invalid format (%s) for -testactivationheight=name@height.", arg)); } - const auto name{arg.substr(0, found)}; + const auto value{arg.substr(found + 1)}; int32_t height; if (!ParseInt32(value, &height) || height < 0 || height >= std::numeric_limits::max()) { throw std::runtime_error(strprintf("Invalid height value (%s) for -testactivationheight=name@height.", arg)); } - if (name == "segwit") { - consensus.SegwitHeight = int{height}; - } else if (name == "bip34") { - consensus.BIP34Height = int{height}; - } else if (name == "dersig") { - consensus.BIP66Height = int{height}; - } else if (name == "cltv") { - consensus.BIP65Height = int{height}; - } else if (name == "csv") { - consensus.CSVHeight = int{height}; + + const auto deployment_name{arg.substr(0, found)}; + if (const auto buried_deployment = GetBuriedDeployment(deployment_name)) { + options.activation_heights[*buried_deployment] = height; } else { throw std::runtime_error(strprintf("Invalid name (%s) for -testactivationheight=name@height.", arg)); } } -} - -void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args) -{ - MaybeUpdateHeights(args, consensus); if (!args.IsArgSet("-vbparams")) return; @@ -541,23 +554,26 @@ void CRegTestParams::UpdateActivationParametersFromArgs(const ArgsManager& args) if (vDeploymentParams.size() < 3 || 4 < vDeploymentParams.size()) { throw std::runtime_error("Version bits parameters malformed, expecting deployment:start:end[:min_activation_height]"); } - int64_t nStartTime, nTimeout; - int min_activation_height = 0; - if (!ParseInt64(vDeploymentParams[1], &nStartTime)) { + CChainParams::VersionBitsParameters vbparams{}; + if (!ParseInt64(vDeploymentParams[1], &vbparams.start_time)) { throw std::runtime_error(strprintf("Invalid nStartTime (%s)", vDeploymentParams[1])); } - if (!ParseInt64(vDeploymentParams[2], &nTimeout)) { + if (!ParseInt64(vDeploymentParams[2], &vbparams.timeout)) { throw std::runtime_error(strprintf("Invalid nTimeout (%s)", vDeploymentParams[2])); } - if (vDeploymentParams.size() >= 4 && !ParseInt32(vDeploymentParams[3], &min_activation_height)) { - throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3])); + if (vDeploymentParams.size() >= 4) { + if (!ParseInt32(vDeploymentParams[3], &vbparams.min_activation_height)) { + throw std::runtime_error(strprintf("Invalid min_activation_height (%s)", vDeploymentParams[3])); + } + } else { + vbparams.min_activation_height = 0; } bool found = false; for (int j=0; j < (int)Consensus::MAX_VERSION_BITS_DEPLOYMENTS; ++j) { if (vDeploymentParams[0] == VersionBitsDeploymentInfo[j].name) { - UpdateVersionBitsParameters(Consensus::DeploymentPos(j), nStartTime, nTimeout, min_activation_height); + options.version_bits_parameters[Consensus::DeploymentPos(j)] = vbparams; found = true; - LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d\n", vDeploymentParams[0], nStartTime, nTimeout, min_activation_height); + LogPrintf("Setting version bits activation parameters for %s to start=%ld, timeout=%ld, min_activation_height=%d\n", vDeploymentParams[0], vbparams.start_time, vbparams.timeout, vbparams.min_activation_height); break; } } @@ -585,7 +601,9 @@ std::unique_ptr CreateChainParams(const ArgsManager& args, c ReadSigNetArgs(args, opts); return std::make_unique(opts); } else if (chain == CBaseChainParams::REGTEST) { - return std::unique_ptr(new CRegTestParams(args)); + auto opts = CChainParams::RegTestOptions{}; + ReadRegTestArgs(args, opts); + return std::make_unique(opts); } throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } diff --git a/src/chainparams.h b/src/chainparams.h index 2f6f3f0907e33..f2e2eb8bc0a28 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -13,8 +13,10 @@ #include #include +#include #include #include +#include #include typedef std::map MapCheckpoints; @@ -131,6 +133,24 @@ class CChainParams std::optional> seeds{}; }; + /** + * VersionBitsParameters holds activation parameters + */ + struct VersionBitsParameters { + int64_t start_time; + int64_t timeout; + int min_activation_height; + }; + + /** + * RegTestOptions holds configurations for creating a regtest CChainParams. + */ + struct RegTestOptions { + std::unordered_map version_bits_parameters{}; + std::unordered_map activation_heights{}; + bool fastprune{false}; + }; + protected: CChainParams() {} diff --git a/src/deploymentinfo.cpp b/src/deploymentinfo.cpp index 246932e56da6a..185a7dcb54ce7 100644 --- a/src/deploymentinfo.cpp +++ b/src/deploymentinfo.cpp @@ -6,6 +6,8 @@ #include +#include + const struct VBDeploymentInfo VersionBitsDeploymentInfo[Consensus::MAX_VERSION_BITS_DEPLOYMENTS] = { { /*.name =*/ "testdummy", @@ -34,3 +36,19 @@ std::string DeploymentName(Consensus::BuriedDeployment dep) } // no default case, so the compiler can warn about missing cases return ""; } + +std::optional GetBuriedDeployment(const std::string_view name) +{ + if (name == "segwit") { + return Consensus::BuriedDeployment::DEPLOYMENT_SEGWIT; + } else if (name == "bip34") { + return Consensus::BuriedDeployment::DEPLOYMENT_HEIGHTINCB; + } else if (name == "dersig") { + return Consensus::BuriedDeployment::DEPLOYMENT_DERSIG; + } else if (name == "cltv") { + return Consensus::BuriedDeployment::DEPLOYMENT_CLTV; + } else if (name == "csv") { + return Consensus::BuriedDeployment::DEPLOYMENT_CSV; + } + return std::nullopt; +} diff --git a/src/deploymentinfo.h b/src/deploymentinfo.h index 8b909dedb462b..72ba297ea0b55 100644 --- a/src/deploymentinfo.h +++ b/src/deploymentinfo.h @@ -7,6 +7,7 @@ #include +#include #include struct VBDeploymentInfo { @@ -26,4 +27,6 @@ inline std::string DeploymentName(Consensus::DeploymentPos pos) return VersionBitsDeploymentInfo[pos].name; } +std::optional GetBuriedDeployment(const std::string_view deployment_name); + #endif // BITCOIN_DEPLOYMENTINFO_H From d938098398814f37fed9b018b44716179cfa4b03 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Wed, 9 Mar 2022 16:17:46 -0500 Subject: [PATCH 3/6] Remove UpdateVersionBitsParameters Moves setting struct member fields from a function to its call site. This improves readability by surfacing the code. --- src/chainparams.cpp | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index e4a5a489a2f5a..2445c379ebedf 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -463,7 +463,9 @@ class CRegTestParams : public CChainParams } for (const auto& [deployment_pos, version_bits_params] : opts.version_bits_parameters) { - UpdateVersionBitsParameters(deployment_pos, version_bits_params.start_time, version_bits_params.timeout, version_bits_params.min_activation_height); + 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; } genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); @@ -511,16 +513,6 @@ class CRegTestParams : public CChainParams bech32_hrp = "bcrt"; } - - /** - * Allows modifying the Version Bits regtest parameters. - */ - void UpdateVersionBitsParameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout, int min_activation_height) - { - consensus.vDeployments[d].nStartTime = nStartTime; - consensus.vDeployments[d].nTimeout = nTimeout; - consensus.vDeployments[d].min_activation_height = min_activation_height; - } }; void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options) From edabbc78a3bc272b2b802e1dbab73d6ed8e31e96 Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 10 Mar 2022 17:21:05 -0500 Subject: [PATCH 4/6] Add factory functions for Main/Test/Sig/Reg chainparams This normalizes the behavior of initializing Main/Test/Sig/Reg chainparams with RegTest/SigNet chainparams. These factory functions can also easily be used from a context without an instantiated ArgsManager, e.g. from libbitcoin kernel code, unlike the existing CreateChainParams method. --- src/chainparams.cpp | 28 ++++++++++++++++++++++++---- src/chainparams.h | 5 +++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 2445c379ebedf..7130141c1ce11 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -582,20 +582,40 @@ const CChainParams &Params() { return *globalChainParams; } +std::unique_ptr CChainParams::SigNet(const SigNetOptions& options) +{ + return std::make_unique(options); +} + +std::unique_ptr CChainParams::RegTest(const RegTestOptions& options) +{ + return std::make_unique(options); +} + +std::unique_ptr CChainParams::Main() +{ + return std::make_unique(); +} + +std::unique_ptr CChainParams::TestNet() +{ + return std::make_unique(); +} + std::unique_ptr CreateChainParams(const ArgsManager& args, const std::string& chain) { if (chain == CBaseChainParams::MAIN) { - return std::unique_ptr(new CMainParams()); + return CChainParams::Main(); } else if (chain == CBaseChainParams::TESTNET) { - return std::unique_ptr(new CTestNetParams()); + return CChainParams::TestNet(); } else if (chain == CBaseChainParams::SIGNET) { auto opts = CChainParams::SigNetOptions{}; ReadSigNetArgs(args, opts); - return std::make_unique(opts); + return CChainParams::SigNet(opts); } else if (chain == CBaseChainParams::REGTEST) { auto opts = CChainParams::RegTestOptions{}; ReadRegTestArgs(args, opts); - return std::make_unique(opts); + return CChainParams::RegTest(opts); } throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain)); } diff --git a/src/chainparams.h b/src/chainparams.h index f2e2eb8bc0a28..30488510d7166 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -151,6 +151,11 @@ class CChainParams bool fastprune{false}; }; + static std::unique_ptr RegTest(const RegTestOptions& options); + static std::unique_ptr SigNet(const SigNetOptions& options); + static std::unique_ptr Main(); + static std::unique_ptr TestNet(); + protected: CChainParams() {} From 382b692a503355df7347efd9c128aff465b5583e Mon Sep 17 00:00:00 2001 From: Carl Dong Date: Thu, 10 Mar 2022 22:13:58 -0500 Subject: [PATCH 5/6] Split non/kernel chainparams Moves chainparams code not using the ArgsManager to the kernel. Subsequently use the kernel chainparams header now where possible in order to further decouple chainparams call sites from gArgs. --- src/Makefile.am | 3 + src/bitcoin-chainstate.cpp | 5 +- src/chainparams.cpp | 506 ----------------------------------- src/chainparams.h | 163 +----------- src/kernel/chainparams.cpp | 532 +++++++++++++++++++++++++++++++++++++ src/kernel/chainparams.h | 187 +++++++++++++ src/node/blockstorage.cpp | 2 +- src/node/mempool_args.cpp | 2 +- src/validation.cpp | 1 + src/validation.h | 4 +- 10 files changed, 732 insertions(+), 673 deletions(-) create mode 100644 src/kernel/chainparams.cpp create mode 100644 src/kernel/chainparams.h diff --git a/src/Makefile.am b/src/Makefile.am index a0c1670287afc..00db655e02213 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -175,6 +175,7 @@ BITCOIN_CORE_H = \ interfaces/node.h \ interfaces/wallet.h \ kernel/chain.h \ + kernel/chainparams.h \ kernel/chainstatemanager_opts.h \ kernel/checks.h \ kernel/coinstats.h \ @@ -651,6 +652,7 @@ libbitcoin_common_a_SOURCES = \ deploymentinfo.cpp \ external_signer.cpp \ init/common.cpp \ + kernel/chainparams.cpp \ key.cpp \ key_io.cpp \ merkleblock.cpp \ @@ -907,6 +909,7 @@ libbitcoinkernel_la_SOURCES = \ hash.cpp \ kernel/chain.cpp \ kernel/checks.cpp \ + kernel/chainparams.cpp \ kernel/coinstats.cpp \ kernel/context.cpp \ kernel/cs_main.cpp \ diff --git a/src/bitcoin-chainstate.cpp b/src/bitcoin-chainstate.cpp index 423fa79c6fe49..12472356609fb 100644 --- a/src/bitcoin-chainstate.cpp +++ b/src/bitcoin-chainstate.cpp @@ -11,6 +11,7 @@ // // It is part of the libbitcoinkernel project. +#include #include #include #include @@ -52,7 +53,7 @@ int main(int argc, char* argv[]) // SETUP: Misc Globals SelectParams(CBaseChainParams::MAIN); - const CChainParams& chainparams = Params(); + auto chainparams = CChainParams::Main(); kernel::Context kernel_context{}; // We can't use a goto here, but we can use an assert since none of the @@ -81,7 +82,7 @@ int main(int argc, char* argv[]) // SETUP: Chainstate const ChainstateManager::Options chainman_opts{ - .chainparams = chainparams, + .chainparams = *chainparams, .datadir = gArgs.GetDataDirNet(), .adjusted_time_callback = NodeClock::now, }; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 7130141c1ce11..6f48ee41b3c12 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -15,369 +15,6 @@ #include -static CBlock CreateGenesisBlock(const char* pszTimestamp, const CScript& genesisOutputScript, uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) -{ - CMutableTransaction txNew; - txNew.nVersion = 1; - txNew.vin.resize(1); - txNew.vout.resize(1); - txNew.vin[0].scriptSig = CScript() << 486604799 << CScriptNum(4) << std::vector((const unsigned char*)pszTimestamp, (const unsigned char*)pszTimestamp + strlen(pszTimestamp)); - txNew.vout[0].nValue = genesisReward; - txNew.vout[0].scriptPubKey = genesisOutputScript; - - CBlock genesis; - genesis.nTime = nTime; - genesis.nBits = nBits; - genesis.nNonce = nNonce; - genesis.nVersion = nVersion; - genesis.vtx.push_back(MakeTransactionRef(std::move(txNew))); - genesis.hashPrevBlock.SetNull(); - genesis.hashMerkleRoot = BlockMerkleRoot(genesis); - return genesis; -} - -/** - * Build the genesis block. Note that the output of its generation - * transaction cannot be spent since it did not originally exist in the - * database. - * - * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1) - * CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0) - * CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73) - * CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B) - * vMerkleTree: 4a5e1e - */ -static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount& genesisReward) -{ - const char* pszTimestamp = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks"; - const CScript genesisOutputScript = CScript() << ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f") << OP_CHECKSIG; - return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward); -} - -/** - * Main network on which people trade goods and services. - */ -class CMainParams : public CChainParams { -public: - CMainParams() { - strNetworkID = CBaseChainParams::MAIN; - consensus.signet_blocks = false; - consensus.signet_challenge.clear(); - consensus.nSubsidyHalvingInterval = 210000; - consensus.script_flag_exceptions.emplace( // BIP16 exception - uint256S("0x00000000000002dc756eebf4f49723ed8d30cc28a5f108eb94b1ba88ac4f9c22"), SCRIPT_VERIFY_NONE); - consensus.script_flag_exceptions.emplace( // Taproot exception - uint256S("0x0000000000000000000f14c35b2d841e986ab5441de8c585d5ffe55ea1e395ad"), SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_WITNESS); - consensus.BIP34Height = 227931; - consensus.BIP34Hash = uint256S("0x000000000000024b89b42a942fe0d9fea3bb44ab7bd1b19115dd6a759c0808b8"); - consensus.BIP65Height = 388381; // 000000000000000004c2b624ed5d7756c508d90fd0da2c7c679febfa6c4735f0 - consensus.BIP66Height = 363725; // 00000000000000000379eaa19dce8c9b722d46ae6a57c2f1a988119488b50931 - consensus.CSVHeight = 419328; // 000000000000000004a1b34462cb8aeebd5799177f7a29cf28f2d1961716b5b5 - consensus.SegwitHeight = 481824; // 0000000000000000001c8018d9cb3b742ef25114f27563e3fc4a1902167f9893 - consensus.MinBIP9WarningHeight = 483840; // segwit activation height + miner confirmation window - consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; - consensus.fPowAllowMinDifficultyBlocks = false; - consensus.fPowNoRetargeting = false; - consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016 - consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay - - // Deployment of Taproot (BIPs 340-342) - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1619222400; // April 24th, 2021 - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1628640000; // August 11th, 2021 - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 709632; // Approximately November 12th, 2021 - - consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000003404ba0801921119f903495e"); - consensus.defaultAssumeValid = uint256S("0x00000000000000000009c97098b5295f7e5f183ac811fb5d1534040adb93cabd"); // 751565 - - /** - * The message start string is designed to be unlikely to occur in normal data. - * The characters are rarely used upper ASCII, not valid as UTF-8, and produce - * a large 32-bit integer with any alignment. - */ - pchMessageStart[0] = 0xf9; - pchMessageStart[1] = 0xbe; - pchMessageStart[2] = 0xb4; - pchMessageStart[3] = 0xd9; - nDefaultPort = 8333; - nPruneAfterHeight = 100000; - m_assumed_blockchain_size = 496; - m_assumed_chain_state_size = 6; - - genesis = CreateGenesisBlock(1231006505, 2083236893, 0x1d00ffff, 1, 50 * COIN); - consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f")); - assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - - // Note that of those which support the service bits prefix, most only support a subset of - // possible options. - // This is fine at runtime as we'll fall back to using them as an addrfetch if they don't support the - // service bits we want, but we should get them updated to support all service bits wanted by any - // release ASAP to avoid it where possible. - vSeeds.emplace_back("seed.bitcoin.sipa.be."); // Pieter Wuille, only supports x1, x5, x9, and xd - vSeeds.emplace_back("dnsseed.bluematt.me."); // Matt Corallo, only supports x9 - vSeeds.emplace_back("dnsseed.bitcoin.dashjr.org."); // Luke Dashjr - vSeeds.emplace_back("seed.bitcoinstats.com."); // Christian Decker, supports x1 - xf - vSeeds.emplace_back("seed.bitcoin.jonasschnelli.ch."); // Jonas Schnelli, only supports x1, x5, x9, and xd - vSeeds.emplace_back("seed.btc.petertodd.org."); // Peter Todd, only supports x1, x5, x9, and xd - vSeeds.emplace_back("seed.bitcoin.sprovoost.nl."); // Sjors Provoost - vSeeds.emplace_back("dnsseed.emzy.de."); // Stephan Oeste - vSeeds.emplace_back("seed.bitcoin.wiz.biz."); // Jason Maurice - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,0); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,5); - base58Prefixes[SECRET_KEY] = std::vector(1,128); - base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; - base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; - - bech32_hrp = "bc"; - - vFixedSeeds = std::vector(std::begin(chainparams_seed_main), std::end(chainparams_seed_main)); - - fDefaultConsistencyChecks = false; - fRequireStandard = true; - m_is_test_chain = false; - m_is_mockable_chain = false; - - checkpointData = { - { - { 11111, uint256S("0x0000000069e244f73d78e8fd29ba2fd2ed618bd6fa2ee92559f542fdb26e7c1d")}, - { 33333, uint256S("0x000000002dd5588a74784eaa7ab0507a18ad16a236e7b1ce69f00d7ddfb5d0a6")}, - { 74000, uint256S("0x0000000000573993a3c9e41ce34471c079dcf5f52a0e824a81e7f953b8661a20")}, - {105000, uint256S("0x00000000000291ce28027faea320c8d2b054b2e0fe44a773f3eefb151d6bdc97")}, - {134444, uint256S("0x00000000000005b12ffd4cd315cd34ffd4a594f430ac814c91184a0d42d2b0fe")}, - {168000, uint256S("0x000000000000099e61ea72015e79632f216fe6cb33d7899acb35b75c8303b763")}, - {193000, uint256S("0x000000000000059f452a5f7340de6682a977387c17010ff6e6c3bd83ca8b1317")}, - {210000, uint256S("0x000000000000048b95347e83192f69cf0366076336c639f9b7228e9ba171342e")}, - {216116, uint256S("0x00000000000001b4f4b433e81ee46494af945cf96014816a4e2370f11b23df4e")}, - {225430, uint256S("0x00000000000001c108384350f74090433e7fcf79a606b8e797f065b130575932")}, - {250000, uint256S("0x000000000000003887df1f29024b06fc2200b55f8af8f35453d7be294df2d214")}, - {279000, uint256S("0x0000000000000001ae8c72a0b0c301f67e3afca10e819efa9041e458e9bd7e40")}, - {295000, uint256S("0x00000000000000004d9b4ef50f0f9d686fd69db2e03af35a100370c64632a983")}, - } - }; - - m_assumeutxo_data = MapAssumeutxo{ - // TODO to be specified in a future patch. - }; - - chainTxData = ChainTxData{ - // Data from RPC: getchaintxstats 4096 00000000000000000009c97098b5295f7e5f183ac811fb5d1534040adb93cabd - .nTime = 1661697692, - .nTxCount = 760120522, - .dTxRate = 2.925802860942233, - }; - } -}; - -/** - * Testnet (v3): public test network which is reset from time to time. - */ -class CTestNetParams : public CChainParams { -public: - CTestNetParams() { - strNetworkID = CBaseChainParams::TESTNET; - consensus.signet_blocks = false; - consensus.signet_challenge.clear(); - consensus.nSubsidyHalvingInterval = 210000; - consensus.script_flag_exceptions.emplace( // BIP16 exception - uint256S("0x00000000dd30457c001f4095d208cc1296b0eed002427aa599874af7a432b105"), SCRIPT_VERIFY_NONE); - consensus.BIP34Height = 21111; - consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8"); - consensus.BIP65Height = 581885; // 00000000007f6655f22f98e72ed80d8b06dc761d5da09df0fa1dc4be4f861eb6 - consensus.BIP66Height = 330776; // 000000002104c8c45e99a8853285a3b592602a3ccde2b832481da85e9e4ba182 - consensus.CSVHeight = 770112; // 00000000025e930139bac5c6c31a403776da130831ab85be56578f3fa75369bb - consensus.SegwitHeight = 834624; // 00000000002b980fcd729daaa248fd9316a5200e9b367f4ff2c42453e84201ca - consensus.MinBIP9WarningHeight = 836640; // segwit activation height + miner confirmation window - consensus.powLimit = uint256S("00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; - consensus.fPowAllowMinDifficultyBlocks = true; - consensus.fPowNoRetargeting = false; - consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains - consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay - - // Deployment of Taproot (BIPs 340-342) - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = 1619222400; // April 24th, 2021 - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = 1628640000; // August 11th, 2021 - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay - - consensus.nMinimumChainWork = uint256S("0x00000000000000000000000000000000000000000000076f6e7cbd0beade5d20"); - consensus.defaultAssumeValid = uint256S("0x0000000000000004877fa2d36316398528de4f347df2f8a96f76613a298ce060"); // 2344474 - - pchMessageStart[0] = 0x0b; - pchMessageStart[1] = 0x11; - pchMessageStart[2] = 0x09; - pchMessageStart[3] = 0x07; - nDefaultPort = 18333; - nPruneAfterHeight = 1000; - m_assumed_blockchain_size = 42; - m_assumed_chain_state_size = 2; - - genesis = CreateGenesisBlock(1296688602, 414098458, 0x1d00ffff, 1, 50 * COIN); - consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943")); - assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - - vFixedSeeds.clear(); - vSeeds.clear(); - // nodes with support for servicebits filtering should be at the top - vSeeds.emplace_back("testnet-seed.bitcoin.jonasschnelli.ch."); - vSeeds.emplace_back("seed.tbtc.petertodd.org."); - vSeeds.emplace_back("seed.testnet.bitcoin.sprovoost.nl."); - vSeeds.emplace_back("testnet-seed.bluematt.me."); // Just a static list of stable node(s), only supports x9 - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); - base58Prefixes[SECRET_KEY] = std::vector(1,239); - base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; - base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - - bech32_hrp = "tb"; - - vFixedSeeds = std::vector(std::begin(chainparams_seed_test), std::end(chainparams_seed_test)); - - fDefaultConsistencyChecks = false; - fRequireStandard = false; - m_is_test_chain = true; - m_is_mockable_chain = false; - - checkpointData = { - { - {546, uint256S("000000002a936ca763904c3c35fce2f3556c559c0214345d31b1bcebf76acb70")}, - } - }; - - m_assumeutxo_data = MapAssumeutxo{ - // TODO to be specified in a future patch. - }; - - chainTxData = ChainTxData{ - // Data from RPC: getchaintxstats 4096 0000000000000004877fa2d36316398528de4f347df2f8a96f76613a298ce060 - .nTime = 1661705221, - .nTxCount = 63531852, - .dTxRate = 0.1079119341520164, - }; - } -}; - -/** - * Signet: test network with an additional consensus parameter (see BIP325). - */ -class SigNetParams : public CChainParams { -public: - explicit SigNetParams(const SigNetOptions& options) - { - std::vector bin; - vSeeds.clear(); - - if (!options.challenge) { - bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae"); - vSeeds.emplace_back("seed.signet.bitcoin.sprovoost.nl."); - - // Hardcoded nodes can be removed once there are more DNS seeds - vSeeds.emplace_back("178.128.221.177"); - vSeeds.emplace_back("v7ajjeirttkbnt32wpy3c6w3emwnfr3fkla7hpxcfokr3ysd3kqtzmqd.onion:38333"); - - consensus.nMinimumChainWork = uint256S("0x000000000000000000000000000000000000000000000000000001291fc22898"); - consensus.defaultAssumeValid = uint256S("0x000000d1a0e224fa4679d2fb2187ba55431c284fa1b74cbc8cfda866fd4d2c09"); // 105495 - m_assumed_blockchain_size = 1; - m_assumed_chain_state_size = 0; - chainTxData = ChainTxData{ - // Data from RPC: getchaintxstats 4096 000000d1a0e224fa4679d2fb2187ba55431c284fa1b74cbc8cfda866fd4d2c09 - .nTime = 1661702566, - .nTxCount = 1903567, - .dTxRate = 0.02336701143027275, - }; - } else { - bin = *options.challenge; - consensus.nMinimumChainWork = uint256{}; - consensus.defaultAssumeValid = uint256{}; - m_assumed_blockchain_size = 0; - m_assumed_chain_state_size = 0; - chainTxData = ChainTxData{ - 0, - 0, - 0, - }; - LogPrintf("Signet with challenge %s\n", HexStr(bin)); - } - - if (options.seeds) { - vSeeds = *options.seeds; - } - - strNetworkID = CBaseChainParams::SIGNET; - consensus.signet_blocks = true; - consensus.signet_challenge.assign(bin.begin(), bin.end()); - consensus.nSubsidyHalvingInterval = 210000; - consensus.BIP34Height = 1; - consensus.BIP34Hash = uint256{}; - consensus.BIP65Height = 1; - consensus.BIP66Height = 1; - consensus.CSVHeight = 1; - consensus.SegwitHeight = 1; - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; - consensus.fPowAllowMinDifficultyBlocks = false; - consensus.fPowNoRetargeting = false; - consensus.nRuleChangeActivationThreshold = 1815; // 90% of 2016 - consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing - consensus.MinBIP9WarningHeight = 0; - consensus.powLimit = uint256S("00000377ae000000000000000000000000000000000000000000000000000000"); - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = Consensus::BIP9Deployment::NEVER_ACTIVE; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay - - // Activation of Taproot (BIPs 340-342) - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay - - // message start is defined as the first 4 bytes of the sha256d of the block script - HashWriter h{}; - h << consensus.signet_challenge; - uint256 hash = h.GetHash(); - memcpy(pchMessageStart, hash.begin(), 4); - - nDefaultPort = 38333; - nPruneAfterHeight = 1000; - - genesis = CreateGenesisBlock(1598918400, 52613770, 0x1e0377ae, 1, 50 * COIN); - consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x00000008819873e925422c1ff0f99f7cc9bbb232af63a077a480a3633bee1ef6")); - assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - - vFixedSeeds.clear(); - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); - base58Prefixes[SECRET_KEY] = std::vector(1,239); - base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; - base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - - bech32_hrp = "tb"; - - fDefaultConsistencyChecks = false; - fRequireStandard = true; - m_is_test_chain = true; - m_is_mockable_chain = false; - } -}; - void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options) { if (args.IsArgSet("-signetseednode")) { @@ -392,129 +29,6 @@ void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& option } } -/** - * Regression test: intended for private networks only. Has minimal difficulty to ensure that - * blocks can be found instantly. - */ -class CRegTestParams : public CChainParams -{ -public: - explicit CRegTestParams(const RegTestOptions& opts) - { - strNetworkID = CBaseChainParams::REGTEST; - consensus.signet_blocks = false; - consensus.signet_challenge.clear(); - consensus.nSubsidyHalvingInterval = 150; - consensus.BIP34Height = 1; // Always active unless overridden - consensus.BIP34Hash = uint256(); - consensus.BIP65Height = 1; // Always active unless overridden - consensus.BIP66Height = 1; // Always active unless overridden - consensus.CSVHeight = 1; // Always active unless overridden - consensus.SegwitHeight = 0; // Always active unless overridden - consensus.MinBIP9WarningHeight = 0; - consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); - consensus.nPowTargetTimespan = 14 * 24 * 60 * 60; // two weeks - consensus.nPowTargetSpacing = 10 * 60; - consensus.fPowAllowMinDifficultyBlocks = true; - consensus.fPowNoRetargeting = true; - consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains - consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016) - - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].min_activation_height = 0; // No activation delay - - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].bit = 2; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nStartTime = Consensus::BIP9Deployment::ALWAYS_ACTIVE; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].nTimeout = Consensus::BIP9Deployment::NO_TIMEOUT; - consensus.vDeployments[Consensus::DEPLOYMENT_TAPROOT].min_activation_height = 0; // No activation delay - - consensus.nMinimumChainWork = uint256{}; - consensus.defaultAssumeValid = uint256{}; - - pchMessageStart[0] = 0xfa; - pchMessageStart[1] = 0xbf; - pchMessageStart[2] = 0xb5; - pchMessageStart[3] = 0xda; - nDefaultPort = 18444; - nPruneAfterHeight = opts.fastprune ? 100 : 1000; - 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; - } - - genesis = CreateGenesisBlock(1296688602, 2, 0x207fffff, 1, 50 * COIN); - consensus.hashGenesisBlock = genesis.GetHash(); - assert(consensus.hashGenesisBlock == uint256S("0x0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")); - assert(genesis.hashMerkleRoot == uint256S("0x4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b")); - - vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. - vSeeds.clear(); - vSeeds.emplace_back("dummySeed.invalid."); - - fDefaultConsistencyChecks = true; - fRequireStandard = true; - m_is_test_chain = true; - m_is_mockable_chain = true; - - checkpointData = { - { - {0, uint256S("0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206")}, - } - }; - - m_assumeutxo_data = MapAssumeutxo{ - { - 110, - {AssumeutxoHash{uint256S("0x1ebbf5850204c0bdb15bf030f47c7fe91d45c44c712697e4509ba67adb01c618")}, 110}, - }, - { - 200, - {AssumeutxoHash{uint256S("0x51c8d11d8b5c1de51543c579736e786aa2736206d1e11e627568029ce092cf62")}, 200}, - }, - }; - - chainTxData = ChainTxData{ - 0, - 0, - 0 - }; - - base58Prefixes[PUBKEY_ADDRESS] = std::vector(1,111); - base58Prefixes[SCRIPT_ADDRESS] = std::vector(1,196); - base58Prefixes[SECRET_KEY] = std::vector(1,239); - base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; - base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; - - bech32_hrp = "bcrt"; - } -}; - void ReadRegTestArgs(const ArgsManager& args, CChainParams::RegTestOptions& options) { if (auto value = args.GetBoolArg("-fastprune")) options.fastprune = *value; @@ -582,26 +96,6 @@ const CChainParams &Params() { return *globalChainParams; } -std::unique_ptr CChainParams::SigNet(const SigNetOptions& options) -{ - return std::make_unique(options); -} - -std::unique_ptr CChainParams::RegTest(const RegTestOptions& options) -{ - return std::make_unique(options); -} - -std::unique_ptr CChainParams::Main() -{ - return std::make_unique(); -} - -std::unique_ptr CChainParams::TestNet() -{ - return std::make_unique(); -} - std::unique_ptr CreateChainParams(const ArgsManager& args, const std::string& chain) { if (chain == CBaseChainParams::MAIN) { diff --git a/src/chainparams.h b/src/chainparams.h index 30488510d7166..cb34d068e1a1b 100644 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -6,6 +6,8 @@ #ifndef BITCOIN_CHAINPARAMS_H #define BITCOIN_CHAINPARAMS_H +#include + #include #include #include @@ -19,167 +21,6 @@ #include #include -typedef std::map MapCheckpoints; - -struct CCheckpointData { - MapCheckpoints mapCheckpoints; - - int GetHeight() const { - const auto& final_checkpoint = mapCheckpoints.rbegin(); - return final_checkpoint->first /* height */; - } -}; - -struct AssumeutxoHash : public BaseHash { - explicit AssumeutxoHash(const uint256& hash) : BaseHash(hash) {} -}; - -/** - * Holds configuration for use during UTXO snapshot load and validation. The contents - * here are security critical, since they dictate which UTXO snapshots are recognized - * as valid. - */ -struct AssumeutxoData { - //! The expected hash of the deserialized UTXO set. - const AssumeutxoHash hash_serialized; - - //! Used to populate the nChainTx value, which is used during BlockManager::LoadBlockIndex(). - //! - //! We need to hardcode the value here because this is computed cumulatively using block data, - //! which we do not necessarily have at the time of snapshot load. - const unsigned int nChainTx; -}; - -using MapAssumeutxo = std::map; - -/** - * Holds various statistics on transactions within a chain. Used to estimate - * verification progress during chain sync. - * - * See also: CChainParams::TxData, GuessVerificationProgress. - */ -struct ChainTxData { - int64_t nTime; //!< UNIX timestamp of last known number of transactions - int64_t nTxCount; //!< total number of transactions between genesis and that timestamp - double dTxRate; //!< estimated number of transactions per second after that timestamp -}; - -/** - * CChainParams defines various tweakable parameters of a given instance of the - * Bitcoin system. - */ -class CChainParams -{ -public: - enum Base58Type { - PUBKEY_ADDRESS, - SCRIPT_ADDRESS, - SECRET_KEY, - EXT_PUBLIC_KEY, - EXT_SECRET_KEY, - - MAX_BASE58_TYPES - }; - - const Consensus::Params& GetConsensus() const { return consensus; } - const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; } - uint16_t GetDefaultPort() const { return nDefaultPort; } - uint16_t GetDefaultPort(Network net) const - { - return net == NET_I2P ? I2P_SAM31_PORT : GetDefaultPort(); - } - uint16_t GetDefaultPort(const std::string& addr) const - { - CNetAddr a; - return a.SetSpecial(addr) ? GetDefaultPort(a.GetNetwork()) : GetDefaultPort(); - } - - const CBlock& GenesisBlock() const { return genesis; } - /** Default value for -checkmempool and -checkblockindex argument */ - bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } - /** Policy: Filter transactions that do not match well-defined patterns */ - bool RequireStandard() const { return fRequireStandard; } - /** If this chain is exclusively used for testing */ - bool IsTestChain() const { return m_is_test_chain; } - /** If this chain allows time to be mocked */ - bool IsMockableChain() const { return m_is_mockable_chain; } - uint64_t PruneAfterHeight() const { return nPruneAfterHeight; } - /** Minimum free space (in GB) needed for data directory */ - uint64_t AssumedBlockchainSize() const { return m_assumed_blockchain_size; } - /** Minimum free space (in GB) needed for data directory when pruned; Does not include prune target*/ - uint64_t AssumedChainStateSize() const { return m_assumed_chain_state_size; } - /** Whether it is possible to mine blocks on demand (no retargeting) */ - bool MineBlocksOnDemand() const { return consensus.fPowNoRetargeting; } - /** Return the network string */ - std::string NetworkIDString() const { return strNetworkID; } - /** Return the list of hostnames to look up for DNS seeds */ - const std::vector& DNSSeeds() const { return vSeeds; } - const std::vector& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } - const std::string& Bech32HRP() const { return bech32_hrp; } - const std::vector& FixedSeeds() const { return vFixedSeeds; } - const CCheckpointData& Checkpoints() const { return checkpointData; } - - //! Get allowed assumeutxo configuration. - //! @see ChainstateManager - const MapAssumeutxo& Assumeutxo() const { return m_assumeutxo_data; } - - const ChainTxData& TxData() const { return chainTxData; } - - /** - * SigNetOptions holds configurations for creating a signet CChainParams. - */ - struct SigNetOptions { - std::optional> challenge{}; - std::optional> seeds{}; - }; - - /** - * VersionBitsParameters holds activation parameters - */ - struct VersionBitsParameters { - int64_t start_time; - int64_t timeout; - int min_activation_height; - }; - - /** - * RegTestOptions holds configurations for creating a regtest CChainParams. - */ - struct RegTestOptions { - std::unordered_map version_bits_parameters{}; - std::unordered_map activation_heights{}; - bool fastprune{false}; - }; - - static std::unique_ptr RegTest(const RegTestOptions& options); - static std::unique_ptr SigNet(const SigNetOptions& options); - static std::unique_ptr Main(); - static std::unique_ptr TestNet(); - -protected: - CChainParams() {} - - Consensus::Params consensus; - CMessageHeader::MessageStartChars pchMessageStart; - uint16_t nDefaultPort; - uint64_t nPruneAfterHeight; - uint64_t m_assumed_blockchain_size; - uint64_t m_assumed_chain_state_size; - std::vector vSeeds; - std::vector base58Prefixes[MAX_BASE58_TYPES]; - std::string bech32_hrp; - std::string strNetworkID; - CBlock genesis; - std::vector vFixedSeeds; - bool fDefaultConsistencyChecks; - bool fRequireStandard; - bool m_is_test_chain; - bool m_is_mockable_chain; - CCheckpointData checkpointData; - MapAssumeutxo m_assumeutxo_data; - ChainTxData chainTxData; -}; - /** * Creates and returns a std::unique_ptr of the chosen chain. * @returns a CChainParams* of the chosen chain. diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp new file mode 100644 index 0000000000000..e0c4aff6f4dee --- /dev/null +++ b/src/kernel/chainparams.cpp @@ -0,0 +1,532 @@ +// Copyright (c) 2010 Satoshi Nakamoto +// Copyright (c) 2009-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include