diff options
Diffstat (limited to 'src/kernel')
-rw-r--r-- | src/kernel/blockmanager_opts.h | 20 | ||||
-rw-r--r-- | src/kernel/chainparams.cpp | 532 | ||||
-rw-r--r-- | src/kernel/chainparams.h | 187 | ||||
-rw-r--r-- | src/kernel/chainstatemanager_opts.h | 6 | ||||
-rw-r--r-- | src/kernel/coinstats.cpp | 7 | ||||
-rw-r--r-- | src/kernel/coinstats.h | 2 | ||||
-rw-r--r-- | src/kernel/context.cpp | 2 | ||||
-rw-r--r-- | src/kernel/context.h | 4 | ||||
-rw-r--r-- | src/kernel/cs_main.cpp | 8 | ||||
-rw-r--r-- | src/kernel/cs_main.h | 22 | ||||
-rw-r--r-- | src/kernel/mempool_entry.h | 174 | ||||
-rw-r--r-- | src/kernel/mempool_options.h | 2 | ||||
-rw-r--r-- | src/kernel/mempool_persist.cpp | 4 | ||||
-rw-r--r-- | src/kernel/mempool_persist.h | 2 |
14 files changed, 959 insertions, 13 deletions
diff --git a/src/kernel/blockmanager_opts.h b/src/kernel/blockmanager_opts.h new file mode 100644 index 0000000000..9dc93b6dd2 --- /dev/null +++ b/src/kernel/blockmanager_opts.h @@ -0,0 +1,20 @@ +// Copyright (c) 2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H +#define BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H + +namespace kernel { + +/** + * An options struct for `BlockManager`, more ergonomically referred to as + * `BlockManager::Options` due to the using-declaration in `BlockManager`. + */ +struct BlockManagerOpts { + uint64_t prune_target{0}; +}; + +} // namespace kernel + +#endif // BITCOIN_KERNEL_BLOCKMANAGER_OPTS_H diff --git a/src/kernel/chainparams.cpp b/src/kernel/chainparams.cpp new file mode 100644 index 0000000000..e0c4aff6f4 --- /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 <kernel/chainparams.h> + +#include <chainparamsseeds.h> +#include <consensus/amount.h> +#include <consensus/merkle.h> +#include <consensus/params.h> +#include <hash.h> +#include <chainparamsbase.h> +#include <logging.h> +#include <primitives/block.h> +#include <primitives/transaction.h> +#include <script/interpreter.h> +#include <script/script.h> +#include <uint256.h> +#include <util/strencodings.h> + +#include <algorithm> +#include <cassert> +#include <cstdint> +#include <cstring> +#include <type_traits> + +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<unsigned char>((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<unsigned char>(1,0); + base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,5); + base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,128); + base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E}; + base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4}; + + bech32_hrp = "bc"; + + vFixedSeeds = std::vector<uint8_t>(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<unsigned char>(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196); + base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239); + base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; + base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; + + bech32_hrp = "tb"; + + vFixedSeeds = std::vector<uint8_t>(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<uint8_t> 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<unsigned char>(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196); + base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(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; + } +}; + +/** + * 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<unsigned char>(1,111); + base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1,196); + base58Prefixes[SECRET_KEY] = std::vector<unsigned char>(1,239); + base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x35, 0x87, 0xCF}; + base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x35, 0x83, 0x94}; + + bech32_hrp = "bcrt"; + } +}; + +std::unique_ptr<const CChainParams> CChainParams::SigNet(const SigNetOptions& options) +{ + return std::make_unique<const SigNetParams>(options); +} + +std::unique_ptr<const CChainParams> CChainParams::RegTest(const RegTestOptions& options) +{ + return std::make_unique<const CRegTestParams>(options); +} + +std::unique_ptr<const CChainParams> CChainParams::Main() +{ + return std::make_unique<const CMainParams>(); +} + +std::unique_ptr<const CChainParams> CChainParams::TestNet() +{ + return std::make_unique<const CTestNetParams>(); +} diff --git a/src/kernel/chainparams.h b/src/kernel/chainparams.h new file mode 100644 index 0000000000..32fe618dbd --- /dev/null +++ b/src/kernel/chainparams.h @@ -0,0 +1,187 @@ +// Copyright (c) 2009-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. + +#ifndef BITCOIN_KERNEL_CHAINPARAMS_H +#define BITCOIN_KERNEL_CHAINPARAMS_H + +#include <consensus/params.h> +#include <netaddress.h> +#include <primitives/block.h> +#include <protocol.h> +#include <uint256.h> +#include <util/hash_type.h> + +#include <cstdint> +#include <iterator> +#include <map> +#include <memory> +#include <optional> +#include <string> +#include <unordered_map> +#include <utility> +#include <vector> + +typedef std::map<int, uint256> MapCheckpoints; + +struct CCheckpointData { + MapCheckpoints mapCheckpoints; + + int GetHeight() const { + const auto& final_checkpoint = mapCheckpoints.rbegin(); + return final_checkpoint->first /* height */; + } +}; + +struct AssumeutxoHash : public BaseHash<uint256> { + 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<int, const AssumeutxoData>; + +/** + * 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<std::string>& DNSSeeds() const { return vSeeds; } + const std::vector<unsigned char>& Base58Prefix(Base58Type type) const { return base58Prefixes[type]; } + const std::string& Bech32HRP() const { return bech32_hrp; } + const std::vector<uint8_t>& 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<std::vector<uint8_t>> challenge{}; + std::optional<std::vector<std::string>> 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<Consensus::DeploymentPos, VersionBitsParameters> version_bits_parameters{}; + std::unordered_map<Consensus::BuriedDeployment, int> activation_heights{}; + bool fastprune{false}; + }; + + static std::unique_ptr<const CChainParams> RegTest(const RegTestOptions& options); + static std::unique_ptr<const CChainParams> SigNet(const SigNetOptions& options); + static std::unique_ptr<const CChainParams> Main(); + static std::unique_ptr<const CChainParams> 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<std::string> vSeeds; + std::vector<unsigned char> base58Prefixes[MAX_BASE58_TYPES]; + std::string bech32_hrp; + std::string strNetworkID; + CBlock genesis; + std::vector<uint8_t> vFixedSeeds; + bool fDefaultConsistencyChecks; + bool fRequireStandard; + bool m_is_test_chain; + bool m_is_mockable_chain; + CCheckpointData checkpointData; + MapAssumeutxo m_assumeutxo_data; + ChainTxData chainTxData; +}; + +#endif // BITCOIN_KERNEL_CHAINPARAMS_H diff --git a/src/kernel/chainstatemanager_opts.h b/src/kernel/chainstatemanager_opts.h index 226bb6031e..2395f60164 100644 --- a/src/kernel/chainstatemanager_opts.h +++ b/src/kernel/chainstatemanager_opts.h @@ -6,6 +6,8 @@ #define BITCOIN_KERNEL_CHAINSTATEMANAGER_OPTS_H #include <arith_uint256.h> +#include <dbwrapper.h> +#include <txdb.h> #include <uint256.h> #include <util/time.h> @@ -27,6 +29,7 @@ namespace kernel { */ struct ChainstateManagerOpts { const CChainParams& chainparams; + fs::path datadir; const std::function<NodeClock::time_point()> adjusted_time_callback{nullptr}; std::optional<bool> check_block_index{}; bool checkpoints_enabled{DEFAULT_CHECKPOINTS_ENABLED}; @@ -36,6 +39,9 @@ struct ChainstateManagerOpts { std::optional<uint256> assumed_valid_block{}; //! If the tip is older than this, the node is considered to be in initial block download. std::chrono::seconds max_tip_age{DEFAULT_MAX_TIP_AGE}; + DBOptions block_tree_db{}; + DBOptions coins_db{}; + CoinsViewOptions coins_view{}; }; } // namespace kernel diff --git a/src/kernel/coinstats.cpp b/src/kernel/coinstats.cpp index 06a4b8c974..4b75c387a6 100644 --- a/src/kernel/coinstats.cpp +++ b/src/kernel/coinstats.cpp @@ -8,6 +8,7 @@ #include <coins.h> #include <crypto/muhash.h> #include <hash.h> +#include <logging.h> #include <node/blockstorage.h> #include <primitives/transaction.h> #include <script/script.h> @@ -19,7 +20,6 @@ #include <uint256.h> #include <util/check.h> #include <util/overflow.h> -#include <util/system.h> #include <validation.h> #include <version.h> @@ -48,8 +48,9 @@ uint64_t GetBogoSize(const CScript& script_pub_key) script_pub_key.size() /* scriptPubKey */; } -CDataStream TxOutSer(const COutPoint& outpoint, const Coin& coin) { - CDataStream ss(SER_DISK, PROTOCOL_VERSION); +DataStream TxOutSer(const COutPoint& outpoint, const Coin& coin) +{ + DataStream ss{}; ss << outpoint; ss << static_cast<uint32_t>(coin.nHeight * 2 + coin.fCoinBase); ss << coin.out; diff --git a/src/kernel/coinstats.h b/src/kernel/coinstats.h index b7c1328e93..54d0e4f664 100644 --- a/src/kernel/coinstats.h +++ b/src/kernel/coinstats.h @@ -72,7 +72,7 @@ struct CCoinsStats { uint64_t GetBogoSize(const CScript& script_pub_key); -CDataStream TxOutSer(const COutPoint& outpoint, const Coin& coin); +DataStream TxOutSer(const COutPoint& outpoint, const Coin& coin); std::optional<CCoinsStats> ComputeUTXOStats(CoinStatsHashType hash_type, CCoinsView* view, node::BlockManager& blockman, const std::function<void()>& interruption_point = {}); } // namespace kernel diff --git a/src/kernel/context.cpp b/src/kernel/context.cpp index 15413c1840..1205da869e 100644 --- a/src/kernel/context.cpp +++ b/src/kernel/context.cpp @@ -21,12 +21,10 @@ Context::Context() LogPrintf("Using the '%s' SHA256 implementation\n", sha256_algo); RandomInit(); ECC_Start(); - ecc_verify_handle.reset(new ECCVerifyHandle()); } Context::~Context() { - ecc_verify_handle.reset(); ECC_Stop(); } diff --git a/src/kernel/context.h b/src/kernel/context.h index 9746ef994b..f11b7b54f0 100644 --- a/src/kernel/context.h +++ b/src/kernel/context.h @@ -7,8 +7,6 @@ #include <memory> -class ECCVerifyHandle; - namespace kernel { //! Context struct holding the kernel library's logically global state, and //! passed to external libbitcoin_kernel functions which need access to this @@ -18,8 +16,6 @@ namespace kernel { //! State stored directly in this struct should be simple. More complex state //! should be stored to std::unique_ptr members pointing to opaque types. struct Context { - std::unique_ptr<ECCVerifyHandle> ecc_verify_handle; - //! Declare default constructor and destructor that are not inline, so code //! instantiating the kernel::Context struct doesn't need to #include class //! definitions for all the unique_ptr members. diff --git a/src/kernel/cs_main.cpp b/src/kernel/cs_main.cpp new file mode 100644 index 0000000000..d27cb7caf3 --- /dev/null +++ b/src/kernel/cs_main.cpp @@ -0,0 +1,8 @@ +// Copyright (c) 2023 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 <kernel/cs_main.h> +#include <sync.h> + +RecursiveMutex cs_main; diff --git a/src/kernel/cs_main.h b/src/kernel/cs_main.h new file mode 100644 index 0000000000..8d03903b8e --- /dev/null +++ b/src/kernel/cs_main.h @@ -0,0 +1,22 @@ +// Copyright (c) 2023 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_KERNEL_CS_MAIN_H +#define BITCOIN_KERNEL_CS_MAIN_H + +#include <sync.h> + +/** + * Mutex to guard access to validation specific variables, such as reading + * or changing the chainstate. + * + * This may also need to be locked when updating the transaction pool, e.g. on + * AcceptToMemoryPool. See CTxMemPool::cs comment for details. + * + * The transaction pool has a separate lock to allow reading from it and the + * chainstate at the same time. + */ +extern RecursiveMutex cs_main; + +#endif // BITCOIN_KERNEL_CS_MAIN_H diff --git a/src/kernel/mempool_entry.h b/src/kernel/mempool_entry.h new file mode 100644 index 0000000000..e1ba4296ef --- /dev/null +++ b/src/kernel/mempool_entry.h @@ -0,0 +1,174 @@ +// Copyright (c) 2009-2022 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_KERNEL_MEMPOOL_ENTRY_H +#define BITCOIN_KERNEL_MEMPOOL_ENTRY_H + +#include <consensus/amount.h> +#include <consensus/validation.h> +#include <core_memusage.h> +#include <policy/policy.h> +#include <policy/settings.h> +#include <primitives/transaction.h> +#include <util/epochguard.h> +#include <util/overflow.h> + +#include <chrono> +#include <functional> +#include <memory> +#include <set> +#include <stddef.h> +#include <stdint.h> + +class CBlockIndex; + +struct LockPoints { + // Will be set to the blockchain height and median time past + // values that would be necessary to satisfy all relative locktime + // constraints (BIP68) of this tx given our view of block chain history + int height{0}; + int64_t time{0}; + // As long as the current chain descends from the highest height block + // containing one of the inputs used in the calculation, then the cached + // values are still valid even after a reorg. + CBlockIndex* maxInputBlock{nullptr}; +}; + +struct CompareIteratorByHash { + // SFINAE for T where T is either a pointer type (e.g., a txiter) or a reference_wrapper<T> + // (e.g. a wrapped CTxMemPoolEntry&) + template <typename T> + bool operator()(const std::reference_wrapper<T>& a, const std::reference_wrapper<T>& b) const + { + return a.get().GetTx().GetHash() < b.get().GetTx().GetHash(); + } + template <typename T> + bool operator()(const T& a, const T& b) const + { + return a->GetTx().GetHash() < b->GetTx().GetHash(); + } +}; + +/** \class CTxMemPoolEntry + * + * CTxMemPoolEntry stores data about the corresponding transaction, as well + * as data about all in-mempool transactions that depend on the transaction + * ("descendant" transactions). + * + * When a new entry is added to the mempool, we update the descendant state + * (nCountWithDescendants, nSizeWithDescendants, and nModFeesWithDescendants) for + * all ancestors of the newly added transaction. + * + */ + +class CTxMemPoolEntry +{ +public: + typedef std::reference_wrapper<const CTxMemPoolEntry> CTxMemPoolEntryRef; + // two aliases, should the types ever diverge + typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Parents; + typedef std::set<CTxMemPoolEntryRef, CompareIteratorByHash> Children; + +private: + const CTransactionRef tx; + mutable Parents m_parents; + mutable Children m_children; + const CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups + const size_t nTxWeight; //!< ... and avoid recomputing tx weight (also used for GetTxSize()) + const size_t nUsageSize; //!< ... and total memory usage + const int64_t nTime; //!< Local time when entering the mempool + const unsigned int entryHeight; //!< Chain height when entering the mempool + const bool spendsCoinbase; //!< keep track of transactions that spend a coinbase + const int64_t sigOpCost; //!< Total sigop cost + CAmount m_modified_fee; //!< Used for determining the priority of the transaction for mining in a block + LockPoints lockPoints; //!< Track the height and time at which tx was final + + // Information about descendants of this transaction that are in the + // mempool; if we remove this transaction we must remove all of these + // descendants as well. + uint64_t nCountWithDescendants{1}; //!< number of descendant transactions + uint64_t nSizeWithDescendants; //!< ... and size + CAmount nModFeesWithDescendants; //!< ... and total fees (all including us) + + // Analogous statistics for ancestor transactions + uint64_t nCountWithAncestors{1}; + uint64_t nSizeWithAncestors; + CAmount nModFeesWithAncestors; + int64_t nSigOpCostWithAncestors; + +public: + CTxMemPoolEntry(const CTransactionRef& tx, CAmount fee, + int64_t time, unsigned int entry_height, + bool spends_coinbase, + int64_t sigops_cost, LockPoints lp) + : tx{tx}, + nFee{fee}, + nTxWeight(GetTransactionWeight(*tx)), + nUsageSize{RecursiveDynamicUsage(tx)}, + nTime{time}, + entryHeight{entry_height}, + spendsCoinbase{spends_coinbase}, + sigOpCost{sigops_cost}, + m_modified_fee{nFee}, + lockPoints{lp}, + nSizeWithDescendants{GetTxSize()}, + nModFeesWithDescendants{nFee}, + nSizeWithAncestors{GetTxSize()}, + nModFeesWithAncestors{nFee}, + nSigOpCostWithAncestors{sigOpCost} {} + + const CTransaction& GetTx() const { return *this->tx; } + CTransactionRef GetSharedTx() const { return this->tx; } + const CAmount& GetFee() const { return nFee; } + size_t GetTxSize() const + { + return GetVirtualTransactionSize(nTxWeight, sigOpCost, ::nBytesPerSigOp); + } + size_t GetTxWeight() const { return nTxWeight; } + std::chrono::seconds GetTime() const { return std::chrono::seconds{nTime}; } + unsigned int GetHeight() const { return entryHeight; } + int64_t GetSigOpCost() const { return sigOpCost; } + CAmount GetModifiedFee() const { return m_modified_fee; } + size_t DynamicMemoryUsage() const { return nUsageSize; } + const LockPoints& GetLockPoints() const { return lockPoints; } + + // Adjusts the descendant state. + void UpdateDescendantState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount); + // Adjusts the ancestor state + void UpdateAncestorState(int64_t modifySize, CAmount modifyFee, int64_t modifyCount, int64_t modifySigOps); + // Updates the modified fees with descendants/ancestors. + void UpdateModifiedFee(CAmount fee_diff) + { + nModFeesWithDescendants = SaturatingAdd(nModFeesWithDescendants, fee_diff); + nModFeesWithAncestors = SaturatingAdd(nModFeesWithAncestors, fee_diff); + m_modified_fee = SaturatingAdd(m_modified_fee, fee_diff); + } + + // Update the LockPoints after a reorg + void UpdateLockPoints(const LockPoints& lp) + { + lockPoints = lp; + } + + uint64_t GetCountWithDescendants() const { return nCountWithDescendants; } + uint64_t GetSizeWithDescendants() const { return nSizeWithDescendants; } + CAmount GetModFeesWithDescendants() const { return nModFeesWithDescendants; } + + bool GetSpendsCoinbase() const { return spendsCoinbase; } + + uint64_t GetCountWithAncestors() const { return nCountWithAncestors; } + uint64_t GetSizeWithAncestors() const { return nSizeWithAncestors; } + CAmount GetModFeesWithAncestors() const { return nModFeesWithAncestors; } + int64_t GetSigOpCostWithAncestors() const { return nSigOpCostWithAncestors; } + + const Parents& GetMemPoolParentsConst() const { return m_parents; } + const Children& GetMemPoolChildrenConst() const { return m_children; } + Parents& GetMemPoolParents() const { return m_parents; } + Children& GetMemPoolChildren() const { return m_children; } + + mutable size_t vTxHashesIdx; //!< Index in mempool's vTxHashes + mutable Epoch::Marker m_epoch_marker; //!< epoch when last touched, useful for graph algorithms +}; + +#endif // BITCOIN_KERNEL_MEMPOOL_ENTRY_H diff --git a/src/kernel/mempool_options.h b/src/kernel/mempool_options.h index dad6f14c39..beb5fca5e9 100644 --- a/src/kernel/mempool_options.h +++ b/src/kernel/mempool_options.h @@ -18,6 +18,8 @@ class CBlockPolicyEstimator; /** Default for -maxmempool, maximum megabytes of mempool memory usage */ static constexpr unsigned int DEFAULT_MAX_MEMPOOL_SIZE_MB{300}; +/** Default for -maxmempool when blocksonly is set */ +static constexpr unsigned int DEFAULT_BLOCKSONLY_MAX_MEMPOOL_SIZE_MB{5}; /** Default for -mempoolexpiry, expiration time for mempool transactions in hours */ static constexpr unsigned int DEFAULT_MEMPOOL_EXPIRY_HOURS{336}; /** Default for -mempoolfullrbf, if the transaction replaceability signaling is ignored */ diff --git a/src/kernel/mempool_persist.cpp b/src/kernel/mempool_persist.cpp index a14b2e6163..71f3aac366 100644 --- a/src/kernel/mempool_persist.cpp +++ b/src/kernel/mempool_persist.cpp @@ -6,7 +6,6 @@ #include <clientversion.h> #include <consensus/amount.h> -#include <fs.h> #include <logging.h> #include <primitives/transaction.h> #include <serialize.h> @@ -15,7 +14,8 @@ #include <sync.h> #include <txmempool.h> #include <uint256.h> -#include <util/system.h> +#include <util/fs.h> +#include <util/fs_helpers.h> #include <util/time.h> #include <validation.h> diff --git a/src/kernel/mempool_persist.h b/src/kernel/mempool_persist.h index ca4917e38b..cb09119e4a 100644 --- a/src/kernel/mempool_persist.h +++ b/src/kernel/mempool_persist.h @@ -5,7 +5,7 @@ #ifndef BITCOIN_KERNEL_MEMPOOL_PERSIST_H #define BITCOIN_KERNEL_MEMPOOL_PERSIST_H -#include <fs.h> +#include <util/fs.h> class Chainstate; class CTxMemPool; |