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 19b5c332f4c26..6f48ee41b3c12 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -15,513 +15,43 @@ #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) +void ReadSigNetArgs(const ArgsManager& args, CChainParams::SigNetOptions& options) { - 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, - }; + if (args.IsArgSet("-signetseednode")) { + options.seeds.emplace(args.GetArgs("-signetseednode")); } -}; - -/** - * Signet: test network with an additional consensus parameter (see BIP325). - */ -class SigNetParams : public CChainParams { -public: - explicit SigNetParams(const ArgsManager& args) { - std::vector bin; - vSeeds.clear(); - - if (!args.IsArgSet("-signetchallenge")) { - 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 { - 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]); - - 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", signet_challenge[0]); - } - - if (args.IsArgSet("-signetseednode")) { - vSeeds = 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__)); } - - 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; + 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 { -public: - explicit CRegTestParams(const ArgsManager& args) { - 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 = args.GetBoolArg("-fastprune", false) ? 100 : 1000; - m_assumed_blockchain_size = 0; - m_assumed_chain_state_size = 0; - - UpdateActivationParametersFromArgs(args); - - 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"; - } - - /** - * 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 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; @@ -530,23 +60,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; } } @@ -566,13 +99,17 @@ const CChainParams &Params() { 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) { - return std::unique_ptr(new SigNetParams(args)); + auto opts = CChainParams::SigNetOptions{}; + ReadSigNetArgs(args, opts); + return CChainParams::SigNet(opts); } else if (chain == CBaseChainParams::REGTEST) { - return std::unique_ptr(new CRegTestParams(args)); + auto opts = CChainParams::RegTestOptions{}; + ReadRegTestArgs(args, 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 66592ffddad06..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 @@ -13,139 +15,12 @@ #include #include +#include #include #include +#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; } -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/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 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