aboutsummaryrefslogtreecommitdiff
path: root/src/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel')
-rw-r--r--src/kernel/blockmanager_opts.h20
-rw-r--r--src/kernel/chainparams.cpp532
-rw-r--r--src/kernel/chainparams.h187
-rw-r--r--src/kernel/chainstatemanager_opts.h6
-rw-r--r--src/kernel/coinstats.cpp7
-rw-r--r--src/kernel/coinstats.h2
-rw-r--r--src/kernel/context.cpp2
-rw-r--r--src/kernel/context.h4
-rw-r--r--src/kernel/cs_main.cpp8
-rw-r--r--src/kernel/cs_main.h22
-rw-r--r--src/kernel/mempool_entry.h174
-rw-r--r--src/kernel/mempool_options.h2
-rw-r--r--src/kernel/mempool_persist.cpp4
-rw-r--r--src/kernel/mempool_persist.h2
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;