aboutsummaryrefslogtreecommitdiff
path: root/src/test/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/util')
-rw-r--r--src/test/util/blockfilter.cpp9
-rw-r--r--src/test/util/blockfilter.h6
-rw-r--r--src/test/util/chainstate.h2
-rw-r--r--src/test/util/mining.cpp48
-rw-r--r--src/test/util/mining.h12
-rw-r--r--src/test/util/net.cpp3
-rw-r--r--src/test/util/poolresourcetester.h129
-rw-r--r--src/test/util/setup_common.cpp66
-rw-r--r--src/test/util/setup_common.h44
-rw-r--r--src/test/util/txmempool.cpp4
10 files changed, 275 insertions, 48 deletions
diff --git a/src/test/util/blockfilter.cpp b/src/test/util/blockfilter.cpp
index ec703c6a7b..a806844e34 100644
--- a/src/test/util/blockfilter.cpp
+++ b/src/test/util/blockfilter.cpp
@@ -8,20 +8,19 @@
#include <node/blockstorage.h>
#include <validation.h>
-using node::ReadBlockFromDisk;
-using node::UndoReadFromDisk;
+using node::BlockManager;
-bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex* block_index, BlockFilter& filter)
+bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex& block_index, BlockFilter& filter, const BlockManager& blockman)
{
LOCK(::cs_main);
CBlock block;
- if (!ReadBlockFromDisk(block, block_index->GetBlockPos(), Params().GetConsensus())) {
+ if (!blockman.ReadBlockFromDisk(block, block_index.GetBlockPos())) {
return false;
}
CBlockUndo block_undo;
- if (block_index->nHeight > 0 && !UndoReadFromDisk(block_undo, block_index)) {
+ if (block_index.nHeight > 0 && !blockman.UndoReadFromDisk(block_undo, block_index)) {
return false;
}
diff --git a/src/test/util/blockfilter.h b/src/test/util/blockfilter.h
index 79d11dcad8..789ce5d3aa 100644
--- a/src/test/util/blockfilter.h
+++ b/src/test/util/blockfilter.h
@@ -6,8 +6,12 @@
#define BITCOIN_TEST_UTIL_BLOCKFILTER_H
#include <blockfilter.h>
+
class CBlockIndex;
+namespace node {
+class BlockManager;
+}
-bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex* block_index, BlockFilter& filter);
+bool ComputeFilter(BlockFilterType filter_type, const CBlockIndex& block_index, BlockFilter& filter, const node::BlockManager& blockman);
#endif // BITCOIN_TEST_UTIL_BLOCKFILTER_H
diff --git a/src/test/util/chainstate.h b/src/test/util/chainstate.h
index e664435e03..bf8f8b5819 100644
--- a/src/test/util/chainstate.h
+++ b/src/test/util/chainstate.h
@@ -6,12 +6,12 @@
#define BITCOIN_TEST_UTIL_CHAINSTATE_H
#include <clientversion.h>
-#include <fs.h>
#include <logging.h>
#include <node/context.h>
#include <node/utxo_snapshot.h>
#include <rpc/blockchain.h>
#include <test/util/setup_common.h>
+#include <util/fs.h>
#include <validation.h>
#include <univalue.h>
diff --git a/src/test/util/mining.cpp b/src/test/util/mining.cpp
index 0df1db84c4..51f4b89512 100644
--- a/src/test/util/mining.cpp
+++ b/src/test/util/mining.cpp
@@ -6,19 +6,22 @@
#include <chainparams.h>
#include <consensus/merkle.h>
+#include <consensus/validation.h>
#include <key_io.h>
#include <node/context.h>
#include <pow.h>
+#include <primitives/transaction.h>
#include <script/standard.h>
#include <test/util/script.h>
#include <util/check.h>
#include <validation.h>
+#include <validationinterface.h>
#include <versionbits.h>
using node::BlockAssembler;
using node::NodeContext;
-CTxIn generatetoaddress(const NodeContext& node, const std::string& address)
+COutPoint generatetoaddress(const NodeContext& node, const std::string& address)
{
const auto dest = DecodeDestination(address);
assert(IsValidDestination(dest));
@@ -58,19 +61,52 @@ std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const
return ret;
}
-CTxIn MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
+COutPoint MineBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey)
{
auto block = PrepareBlock(node, coinbase_scriptPubKey);
+ auto valid = MineBlock(node, block);
+ assert(!valid.IsNull());
+ return valid;
+}
+
+struct BlockValidationStateCatcher : public CValidationInterface {
+ const uint256 m_hash;
+ std::optional<BlockValidationState> m_state;
+ BlockValidationStateCatcher(const uint256& hash)
+ : m_hash{hash},
+ m_state{} {}
+
+protected:
+ void BlockChecked(const CBlock& block, const BlockValidationState& state) override
+ {
+ if (block.GetHash() != m_hash) return;
+ m_state = state;
+ }
+};
+
+COutPoint MineBlock(const NodeContext& node, std::shared_ptr<CBlock>& block)
+{
while (!CheckProofOfWork(block->GetHash(), block->nBits, Params().GetConsensus())) {
++block->nNonce;
assert(block->nNonce);
}
- bool processed{Assert(node.chainman)->ProcessNewBlock(block, true, true, nullptr)};
- assert(processed);
-
- return CTxIn{block->vtx[0]->GetHash(), 0};
+ auto& chainman{*Assert(node.chainman)};
+ const auto old_height = WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight());
+ bool new_block;
+ BlockValidationStateCatcher bvsc{block->GetHash()};
+ RegisterValidationInterface(&bvsc);
+ const bool processed{chainman.ProcessNewBlock(block, true, true, &new_block)};
+ const bool duplicate{!new_block && processed};
+ assert(!duplicate);
+ UnregisterValidationInterface(&bvsc);
+ SyncWithValidationInterfaceQueue();
+ const bool was_valid{bvsc.m_state && bvsc.m_state->IsValid()};
+ assert(old_height + was_valid == WITH_LOCK(chainman.GetMutex(), return chainman.ActiveHeight()));
+
+ if (was_valid) return {block->vtx[0]->GetHash(), 0};
+ return {};
}
std::shared_ptr<CBlock> PrepareBlock(const NodeContext& node, const CScript& coinbase_scriptPubKey,
diff --git a/src/test/util/mining.h b/src/test/util/mining.h
index 70b1f7b3fb..3f071257f1 100644
--- a/src/test/util/mining.h
+++ b/src/test/util/mining.h
@@ -13,8 +13,8 @@
class CBlock;
class CChainParams;
+class COutPoint;
class CScript;
-class CTxIn;
namespace node {
struct NodeContext;
} // namespace node
@@ -23,7 +23,13 @@ struct NodeContext;
std::vector<std::shared_ptr<CBlock>> CreateBlockChain(size_t total_height, const CChainParams& params);
/** Returns the generated coin */
-CTxIn MineBlock(const node::NodeContext&, const CScript& coinbase_scriptPubKey);
+COutPoint MineBlock(const node::NodeContext&, const CScript& coinbase_scriptPubKey);
+
+/**
+ * Returns the generated coin (or Null if the block was invalid).
+ * It is recommended to call RegenerateCommitments before mining the block to avoid merkle tree mismatches.
+ **/
+COutPoint MineBlock(const node::NodeContext&, std::shared_ptr<CBlock>& block);
/** Prepare a block to be mined */
std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext&, const CScript& coinbase_scriptPubKey);
@@ -31,6 +37,6 @@ std::shared_ptr<CBlock> PrepareBlock(const node::NodeContext& node, const CScrip
const node::BlockAssembler::Options& assembler_options);
/** RPC-like helper function, returns the generated coin */
-CTxIn generatetoaddress(const node::NodeContext&, const std::string& address);
+COutPoint generatetoaddress(const node::NodeContext&, const std::string& address);
#endif // BITCOIN_TEST_UTIL_MINING_H
diff --git a/src/test/util/net.cpp b/src/test/util/net.cpp
index 070a6a1c50..3f72384b3b 100644
--- a/src/test/util/net.cpp
+++ b/src/test/util/net.cpp
@@ -66,7 +66,7 @@ void ConnmanTestMsg::NodeReceiveMsgBytes(CNode& node, Span<const uint8_t> msg_by
{
assert(node.ReceiveMsgBytes(msg_bytes, complete));
if (complete) {
- node.MarkReceivedMsgsForProcessing(nReceiveFloodSize);
+ node.MarkReceivedMsgsForProcessing();
}
}
@@ -84,6 +84,7 @@ bool ConnmanTestMsg::ReceiveMsgFrom(CNode& node, CSerializedNetMsg& ser_msg) con
std::vector<NodeEvictionCandidate> GetRandomNodeEvictionCandidates(int n_candidates, FastRandomContext& random_context)
{
std::vector<NodeEvictionCandidate> candidates;
+ candidates.reserve(n_candidates);
for (int id = 0; id < n_candidates; ++id) {
candidates.push_back({
/*id=*/id,
diff --git a/src/test/util/poolresourcetester.h b/src/test/util/poolresourcetester.h
new file mode 100644
index 0000000000..93f62eb2a9
--- /dev/null
+++ b/src/test/util/poolresourcetester.h
@@ -0,0 +1,129 @@
+// 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_TEST_UTIL_POOLRESOURCETESTER_H
+#define BITCOIN_TEST_UTIL_POOLRESOURCETESTER_H
+
+#include <support/allocators/pool.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
+#include <vector>
+
+/**
+ * Helper to get access to private parts of PoolResource. Used in unit tests and in the fuzzer
+ */
+class PoolResourceTester
+{
+ struct PtrAndBytes {
+ uintptr_t ptr;
+ std::size_t size;
+
+ PtrAndBytes(const void* p, std::size_t s)
+ : ptr(reinterpret_cast<uintptr_t>(p)), size(s)
+ {
+ }
+
+ /**
+ * defines a sort ordering by the pointer value
+ */
+ friend bool operator<(PtrAndBytes const& a, PtrAndBytes const& b)
+ {
+ return a.ptr < b.ptr;
+ }
+ };
+
+public:
+ /**
+ * Extracts the number of elements per freelist
+ */
+ template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+ static std::vector<std::size_t> FreeListSizes(const PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& resource)
+ {
+ auto sizes = std::vector<std::size_t>();
+ for (const auto* ptr : resource.m_free_lists) {
+ size_t size = 0;
+ while (ptr != nullptr) {
+ ++size;
+ ptr = ptr->m_next;
+ }
+ sizes.push_back(size);
+ }
+ return sizes;
+ }
+
+ /**
+ * How many bytes are still available from the last allocated chunk
+ */
+ template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+ static std::size_t AvailableMemoryFromChunk(const PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& resource)
+ {
+ return resource.m_available_memory_end - resource.m_available_memory_it;
+ }
+
+ /**
+ * Once all blocks are given back to the resource, tests that the freelists are consistent:
+ *
+ * * All data in the freelists must come from the chunks
+ * * Memory doesn't overlap
+ * * Each byte in the chunks can be accounted for in either the freelist or as available bytes.
+ */
+ template <std::size_t MAX_BLOCK_SIZE_BYTES, std::size_t ALIGN_BYTES>
+ static void CheckAllDataAccountedFor(const PoolResource<MAX_BLOCK_SIZE_BYTES, ALIGN_BYTES>& resource)
+ {
+ // collect all free blocks by iterating all freelists
+ std::vector<PtrAndBytes> free_blocks;
+ for (std::size_t freelist_idx = 0; freelist_idx < resource.m_free_lists.size(); ++freelist_idx) {
+ std::size_t bytes = freelist_idx * resource.ELEM_ALIGN_BYTES;
+ auto* ptr = resource.m_free_lists[freelist_idx];
+ while (ptr != nullptr) {
+ free_blocks.emplace_back(ptr, bytes);
+ ptr = ptr->m_next;
+ }
+ }
+ // also add whatever has not yet been used for blocks
+ auto num_available_bytes = resource.m_available_memory_end - resource.m_available_memory_it;
+ if (num_available_bytes > 0) {
+ free_blocks.emplace_back(resource.m_available_memory_it, num_available_bytes);
+ }
+
+ // collect all chunks
+ std::vector<PtrAndBytes> chunks;
+ for (const std::byte* ptr : resource.m_allocated_chunks) {
+ chunks.emplace_back(ptr, resource.ChunkSizeBytes());
+ }
+
+ // now we have all the data from all freelists on the one hand side, and all chunks on the other hand side.
+ // To check if all of them match, sort by address and iterate.
+ std::sort(free_blocks.begin(), free_blocks.end());
+ std::sort(chunks.begin(), chunks.end());
+
+ auto chunk_it = chunks.begin();
+ auto chunk_ptr_remaining = chunk_it->ptr;
+ auto chunk_size_remaining = chunk_it->size;
+ for (const auto& free_block : free_blocks) {
+ if (chunk_size_remaining == 0) {
+ assert(chunk_it != chunks.end());
+ ++chunk_it;
+ assert(chunk_it != chunks.end());
+ chunk_ptr_remaining = chunk_it->ptr;
+ chunk_size_remaining = chunk_it->size;
+ }
+ assert(free_block.ptr == chunk_ptr_remaining); // ensure addresses match
+ assert(free_block.size <= chunk_size_remaining); // ensure no overflow
+ assert((free_block.ptr & (resource.ELEM_ALIGN_BYTES - 1)) == 0); // ensure correct alignment
+ chunk_ptr_remaining += free_block.size;
+ chunk_size_remaining -= free_block.size;
+ }
+ // ensure we are at the end of the chunks
+ assert(chunk_ptr_remaining == chunk_it->ptr + chunk_it->size);
+ ++chunk_it;
+ assert(chunk_it == chunks.end());
+ assert(chunk_size_remaining == 0);
+ }
+};
+
+#endif // BITCOIN_TEST_UTIL_POOLRESOURCETESTER_H
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 58593c9d5b..93a60db832 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -9,6 +9,7 @@
#include <addrman.h>
#include <banman.h>
#include <chainparams.h>
+#include <common/system.h>
#include <common/url.h>
#include <consensus/consensus.h>
#include <consensus/params.h>
@@ -23,6 +24,7 @@
#include <node/blockstorage.h>
#include <node/chainstate.h>
#include <node/context.h>
+#include <node/kernel_notifications.h>
#include <node/mempool_args.h>
#include <node/miner.h>
#include <node/validation_cache_args.h>
@@ -42,6 +44,7 @@
#include <timedata.h>
#include <txdb.h>
#include <txmempool.h>
+#include <util/chaintype.h>
#include <util/strencodings.h>
#include <util/string.h>
#include <util/thread.h>
@@ -60,7 +63,9 @@
using kernel::ValidationCacheSizes;
using node::ApplyArgsManOptions;
using node::BlockAssembler;
+using node::BlockManager;
using node::CalculateCacheSizes;
+using node::KernelNotifications;
using node::LoadChainstate;
using node::RegenerateCommitments;
using node::VerifyLoadedChainstate;
@@ -97,7 +102,7 @@ std::ostream& operator<<(std::ostream& os, const uint256& num)
return os;
}
-BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::vector<const char*>& extra_args)
+BasicTestingSetup::BasicTestingSetup(const ChainType chainType, const std::vector<const char*>& extra_args)
: m_path_root{fs::temp_directory_path() / "test_common_" PACKAGE_NAME / g_insecure_rand_ctx_temp_path.rand256().ToString()},
m_args{}
{
@@ -131,7 +136,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
throw std::runtime_error{error};
}
}
- SelectParams(chainName);
+ SelectParams(chainType);
SeedInsecureRand();
if (G_TEST_LOG_FUN) LogInstance().PushBackCallback(G_TEST_LOG_FUN);
InitLogging(*m_node.args);
@@ -152,6 +157,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve
noui_connect();
noui_connected = true;
}
+ node::g_indexes_ready_to_sync = true;
}
BasicTestingSetup::~BasicTestingSetup()
@@ -162,8 +168,8 @@ BasicTestingSetup::~BasicTestingSetup()
gArgs.ClearArgs();
}
-ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::vector<const char*>& extra_args)
- : BasicTestingSetup(chainName, extra_args)
+ChainTestingSetup::ChainTestingSetup(const ChainType chainType, const std::vector<const char*>& extra_args)
+ : BasicTestingSetup(chainType, extra_args)
{
const CChainParams& chainparams = Params();
@@ -173,18 +179,25 @@ ChainTestingSetup::ChainTestingSetup(const std::string& chainName, const std::ve
m_node.scheduler->m_service_thread = std::thread(util::TraceThread, "scheduler", [&] { m_node.scheduler->serviceQueue(); });
GetMainSignals().RegisterBackgroundSignalScheduler(*m_node.scheduler);
- m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(*m_node.args));
+ m_node.fee_estimator = std::make_unique<CBlockPolicyEstimator>(FeeestPath(*m_node.args), DEFAULT_ACCEPT_STALE_FEE_ESTIMATES);
m_node.mempool = std::make_unique<CTxMemPool>(MemPoolOptionsForTest(m_node));
m_cache_sizes = CalculateCacheSizes(m_args);
+ m_node.notifications = std::make_unique<KernelNotifications>();
+
const ChainstateManager::Options chainman_opts{
.chainparams = chainparams,
.datadir = m_args.GetDataDirNet(),
.adjusted_time_callback = GetAdjustedTime,
.check_block_index = true,
+ .notifications = *m_node.notifications,
+ };
+ const BlockManager::Options blockman_opts{
+ .chainparams = chainman_opts.chainparams,
+ .blocks_dir = m_args.GetBlocksDirPath(),
};
- m_node.chainman = std::make_unique<ChainstateManager>(chainman_opts, node::BlockManager::Options{});
+ m_node.chainman = std::make_unique<ChainstateManager>(chainman_opts, blockman_opts);
m_node.chainman->m_blockman.m_block_tree_db = std::make_unique<CBlockTreeDB>(DBParams{
.path = m_args.GetDataDirNet() / "blocks" / "index",
.cache_bytes = static_cast<size_t>(m_cache_sizes.block_tree_db),
@@ -210,7 +223,7 @@ ChainTestingSetup::~ChainTestingSetup()
m_node.chainman.reset();
}
-void TestingSetup::LoadVerifyActivateChainstate()
+void ChainTestingSetup::LoadVerifyActivateChainstate()
{
auto& chainman{*Assert(m_node.chainman)};
node::ChainstateLoadOptions options;
@@ -236,14 +249,14 @@ void TestingSetup::LoadVerifyActivateChainstate()
}
TestingSetup::TestingSetup(
- const std::string& chainName,
+ const ChainType chainType,
const std::vector<const char*>& extra_args,
const bool coins_db_in_memory,
const bool block_tree_db_in_memory)
- : ChainTestingSetup(chainName, extra_args),
- m_coins_db_in_memory(coins_db_in_memory),
- m_block_tree_db_in_memory(block_tree_db_in_memory)
+ : ChainTestingSetup(chainType, extra_args)
{
+ m_coins_db_in_memory = coins_db_in_memory;
+ m_block_tree_db_in_memory = block_tree_db_in_memory;
// Ideally we'd move all the RPC tests to the functional testing framework
// instead of unit tests, but for now we need these here.
RegisterAllCoreRPCCommands(tableRPC);
@@ -267,11 +280,11 @@ TestingSetup::TestingSetup(
}
TestChain100Setup::TestChain100Setup(
- const std::string& chain_name,
+ const ChainType chain_type,
const std::vector<const char*>& extra_args,
const bool coins_db_in_memory,
const bool block_tree_db_in_memory)
- : TestingSetup{CBaseChainParams::REGTEST, extra_args, coins_db_in_memory, block_tree_db_in_memory}
+ : TestingSetup{ChainType::REGTEST, extra_args, coins_db_in_memory, block_tree_db_in_memory}
{
SetMockTime(1598887952);
constexpr std::array<unsigned char, 32> vchKey = {
@@ -432,6 +445,33 @@ std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContex
return mempool_transactions;
}
+void TestChain100Setup::MockMempoolMinFee(const CFeeRate& target_feerate)
+{
+ LOCK2(cs_main, m_node.mempool->cs);
+ // Transactions in the mempool will affect the new minimum feerate.
+ assert(m_node.mempool->size() == 0);
+ // The target feerate cannot be too low...
+ // ...otherwise the transaction's feerate will need to be negative.
+ assert(target_feerate > m_node.mempool->m_incremental_relay_feerate);
+ // ...otherwise this is not meaningful. The feerate policy uses the maximum of both feerates.
+ assert(target_feerate > m_node.mempool->m_min_relay_feerate);
+
+ // Manually create an invalid transaction. Manually set the fee in the CTxMemPoolEntry to
+ // achieve the exact target feerate.
+ CMutableTransaction mtx = CMutableTransaction();
+ mtx.vin.push_back(CTxIn{COutPoint{g_insecure_rand_ctx.rand256(), 0}});
+ mtx.vout.push_back(CTxOut(1 * COIN, GetScriptForDestination(WitnessV0ScriptHash(CScript() << OP_TRUE))));
+ const auto tx{MakeTransactionRef(mtx)};
+ LockPoints lp;
+ // The new mempool min feerate is equal to the removed package's feerate + incremental feerate.
+ const auto tx_fee = target_feerate.GetFee(GetVirtualTransactionSize(*tx)) -
+ m_node.mempool->m_incremental_relay_feerate.GetFee(GetVirtualTransactionSize(*tx));
+ m_node.mempool->addUnchecked(CTxMemPoolEntry(tx, /*fee=*/tx_fee,
+ /*time=*/0, /*entry_height=*/1,
+ /*spends_coinbase=*/true, /*sigops_cost=*/1, lp));
+ m_node.mempool->TrimToSize(0);
+ assert(m_node.mempool->GetMinFee() == target_feerate);
+}
/**
* @returns a real block (0000000000013b8ab2cd513b0261a14096412195a72a0c4827d229dcc7e0f7af)
* with 9 txs.
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index 8874db7e75..b7429df02c 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -5,24 +5,25 @@
#ifndef BITCOIN_TEST_UTIL_SETUP_COMMON_H
#define BITCOIN_TEST_UTIL_SETUP_COMMON_H
-#include <chainparamsbase.h>
-#include <fs.h>
+#include <common/args.h>
#include <key.h>
#include <node/caches.h>
-#include <node/context.h>
+#include <node/context.h> // IWYU pragma: export
#include <primitives/transaction.h>
#include <pubkey.h>
#include <random.h>
#include <stdexcept>
+#include <util/chaintype.h>
#include <util/check.h>
+#include <util/fs.h>
#include <util/string.h>
-#include <util/system.h>
#include <util/vector.h>
#include <functional>
#include <type_traits>
#include <vector>
+class CFeeRate;
class Chainstate;
/** This is connected to the logger. Can be used to redirect logs to any other log */
@@ -79,7 +80,7 @@ static constexpr CAmount CENT{1000000};
struct BasicTestingSetup {
node::NodeContext m_node; // keep as first member to be destructed last
- explicit BasicTestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector<const char*>& extra_args = {});
+ explicit BasicTestingSetup(const ChainType chainType = ChainType::MAIN, const std::vector<const char*>& extra_args = {});
~BasicTestingSetup();
const fs::path m_path_root;
@@ -92,21 +93,21 @@ struct BasicTestingSetup {
*/
struct ChainTestingSetup : public BasicTestingSetup {
node::CacheSizes m_cache_sizes{};
+ bool m_coins_db_in_memory{true};
+ bool m_block_tree_db_in_memory{true};
- explicit ChainTestingSetup(const std::string& chainName = CBaseChainParams::MAIN, const std::vector<const char*>& extra_args = {});
+ explicit ChainTestingSetup(const ChainType chainType = ChainType::MAIN, const std::vector<const char*>& extra_args = {});
~ChainTestingSetup();
+
+ // Supplies a chainstate, if one is needed
+ void LoadVerifyActivateChainstate();
};
/** Testing setup that configures a complete environment.
*/
struct TestingSetup : public ChainTestingSetup {
- bool m_coins_db_in_memory{true};
- bool m_block_tree_db_in_memory{true};
-
- void LoadVerifyActivateChainstate();
-
explicit TestingSetup(
- const std::string& chainName = CBaseChainParams::MAIN,
+ const ChainType chainType = ChainType::MAIN,
const std::vector<const char*>& extra_args = {},
const bool coins_db_in_memory = true,
const bool block_tree_db_in_memory = true);
@@ -115,7 +116,7 @@ struct TestingSetup : public ChainTestingSetup {
/** Identical to TestingSetup, but chain set to regtest */
struct RegTestingSetup : public TestingSetup {
RegTestingSetup()
- : TestingSetup{CBaseChainParams::REGTEST} {}
+ : TestingSetup{ChainType::REGTEST} {}
};
class CBlock;
@@ -127,7 +128,7 @@ class CScript;
*/
struct TestChain100Setup : public TestingSetup {
TestChain100Setup(
- const std::string& chain_name = CBaseChainParams::REGTEST,
+ const ChainType chain_type = ChainType::REGTEST,
const std::vector<const char*>& extra_args = {},
const bool coins_db_in_memory = true,
const bool block_tree_db_in_memory = true);
@@ -185,6 +186,17 @@ struct TestChain100Setup : public TestingSetup {
*/
std::vector<CTransactionRef> PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit);
+ /** Mock the mempool minimum feerate by adding a transaction and calling TrimToSize(0),
+ * simulating the mempool "reaching capacity" and evicting by descendant feerate. Note that
+ * this clears the mempool, and the new minimum feerate will depend on the maximum feerate of
+ * transactions removed, so this must be called while the mempool is empty.
+ *
+ * @param target_feerate The new mempool minimum feerate after this function returns.
+ * Must be above max(incremental feerate, min relay feerate),
+ * or 1sat/vB with default settings.
+ */
+ void MockMempoolMinFee(const CFeeRate& target_feerate);
+
std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
CKey coinbaseKey; // private/public key needed to spend coinbase transactions
};
@@ -194,7 +206,7 @@ struct TestChain100Setup : public TestingSetup {
* be used in "hot loops", for example fuzzing or benchmarking.
*/
template <class T = const BasicTestingSetup>
-std::unique_ptr<T> MakeNoLogFileContext(const std::string& chain_name = CBaseChainParams::REGTEST, const std::vector<const char*>& extra_args = {})
+std::unique_ptr<T> MakeNoLogFileContext(const ChainType chain_type = ChainType::REGTEST, const std::vector<const char*>& extra_args = {})
{
const std::vector<const char*> arguments = Cat(
{
@@ -203,7 +215,7 @@ std::unique_ptr<T> MakeNoLogFileContext(const std::string& chain_name = CBaseCha
},
extra_args);
- return std::make_unique<T>(chain_name, arguments);
+ return std::make_unique<T>(chain_type, arguments);
}
CBlock getBlock13b8a();
diff --git a/src/test/util/txmempool.cpp b/src/test/util/txmempool.cpp
index 1873cf5ec8..4797d9c310 100644
--- a/src/test/util/txmempool.cpp
+++ b/src/test/util/txmempool.cpp
@@ -22,8 +22,8 @@ CTxMemPool::Options MemPoolOptionsForTest(const NodeContext& node)
// chainparams.DefaultConsistencyChecks for tests
.check_ratio = 1,
};
- const auto err{ApplyArgsManOptions(*node.args, ::Params(), mempool_opts)};
- Assert(!err);
+ const auto result{ApplyArgsManOptions(*node.args, ::Params(), mempool_opts)};
+ Assert(result);
return mempool_opts;
}