15#include <validation.h>
17#include <test/util/mining.h>
18#include <test/util/setup_common.h>
33static const CScript
SCRIPT_SIG = CScript() << std::vector<uint8_t>(100, 0xff)
39 std::vector<CTxIn> utxos;
42 for (
size_t i = 0; i < n; ++i) {
56 tx.
vin.emplace_back(txin);
63static std::vector<CTransactionRef>
65 auto firstTx =
toTx(config, std::move(utxo));
68 std::vector<CTransactionRef> chain = {firstTx};
69 chain.reserve(chainLength);
70 while (chain.size() < chainLength) {
71 const COutPoint parent(chain.back()->GetId(), 0);
72 const Amount inAmount(chain.back()->vout[0].nValue);
78 assert(chain.size() == chainLength);
87 const size_t treeDepth) {
90 for (
size_t i = 0; i <= treeDepth; ++i) {
91 txs += std::pow(2, i);
93 const size_t leafs = std::pow(2, treeDepth);
95 std::vector<CTransactionRef> chain;
98 std::queue<CTransactionRef> queue;
100 auto tx =
toTx(config, std::move(txin));
102 chain.emplace_back(tx);
113 const Amount inAmount = txin1->vout[0].nValue + txin2->vout[0].nValue;
115 tx.
vin.emplace_back(CTxIn(COutPoint(txin1->GetId(), 0),
SCRIPT_SIG));
116 tx.
vin.emplace_back(CTxIn(COutPoint(txin2->GetId(), 0),
SCRIPT_SIG));
120 chain.push_back(txref);
124 queue.emplace(txref);
126 assert(chain.size() == txs);
132 const std::vector<CTransactionRef> chainedTxs) {
134 Chainstate &activeChainState = chainman->ActiveChainstate();
137 assert(mempool.size() == 0);
141 for (
const auto &tx : chainedTxs) {
159 size_t chainSizePerBlock,
bool includeMempoolTxRemoval) {
161 std::vector<std::vector<CTransactionRef>> chains;
162 for (
auto &utxo : utxos) {
168 Chainstate &activeChainState = chainman->ActiveChainstate();
172 assert(tipBeforeInvalidate !=
nullptr);
177 assert(mempool.size() == 0);
180 TestMemPoolEntryHelper entry;
182 for (
const auto &chain : chains) {
185 for (
const auto &tx : chain) {
186 mempool.addUnchecked(entry.FromTx(tx));
189 assert(mempool.size() == chain.size());
191 assert(mempool.size() == 0);
196 if (blockToInvalidate ==
nullptr) {
197 blockToInvalidate = activeChainState.
m_chain.
Tip();
214 assert(mempool.size() == reorgDepth * chainSizePerBlock);
216 if (!includeMempoolTxRemoval) {
232 assert(mempool.size() == 0);
239 const std::vector<std::vector<CTransactionRef>> &chains) {
240 TestMemPoolEntryHelper entry;
244 Chainstate &activeChainState = chainman->ActiveChainstate();
249 for (
const auto &chain : chains) {
251 for (
const auto &tx : chain) {
252 mempool.addUnchecked(entry.FromTx(tx));
256 assert(mempool.size() == txCount);
258 const CScript dummy = CScript() <<
OP_TRUE;
262 .CreateNewBlock(dummy);
265 assert(blocktemplate->block.vtx.size() == txCount + 1);
271 const std::vector<std::vector<CTransactionRef>> &chains,
272 bool revFee =
true) {
273 std::list<CTxMemPool> pools;
286 pools.emplace_back(mempool_opts);
288 TestMemPoolEntryHelper entry;
295 for (
const auto &chain : chains) {
297 entry.nFee += int64_t(chain.size()) *
SATOSHI;
300 for (
const auto &tx : chain) {
302 entry.nFee += feeBump;
308 entry.nFee += int64_t(chain.size()) *
SATOSHI;
314 auto it = pools.begin();
317 assert(it != pools.end());
320 while (
auto prevSize = pool.size()) {
321 pool.TrimToSize(pool.DynamicMemoryUsage() * 99 / 100);
322 assert(pool.size() < prevSize);
329 RegTestingSetup test_setup{};
330 const Config &config = test_setup.m_node.chainman->GetConfig();
332 config,
createUTXOs(config, 1, test_setup.m_node).back(), 50);
333 benchATMP(test_setup.m_node, bench, chainedTxs);
338 RegTestingSetup test_setup{};
339 const Config &config = test_setup.m_node.chainman->GetConfig();
341 config,
createUTXOs(config, 1, test_setup.m_node).back(), 500);
342 benchATMP(test_setup.m_node, bench, chainedTxs);
347 RegTestingSetup test_setup{};
348 const Config &config = test_setup.m_node.chainman->GetConfig();
349 const std::vector<CTransactionRef> chainedTxs =
351 assert(chainedTxs.size() == 63);
352 benchATMP(test_setup.m_node, bench, chainedTxs);
357 RegTestingSetup test_setup{};
358 const Config &config = test_setup.m_node.chainman->GetConfig();
359 const std::vector<CTransactionRef> chainedTxs =
361 assert(chainedTxs.size() == 511);
362 benchATMP(test_setup.m_node, bench, chainedTxs);
368 RegTestingSetup test_setup{};
369 const Config &config = test_setup.m_node.chainman->GetConfig();
370 benchReorg(config, test_setup.m_node, bench, 10, 50,
true);
376 RegTestingSetup test_setup{};
377 const Config &config = test_setup.m_node.chainman->GetConfig();
378 benchReorg(config, test_setup.m_node, bench, 10, 500,
true);
385 RegTestingSetup test_setup{};
386 const Config &config = test_setup.m_node.chainman->GetConfig();
387 benchReorg(config, test_setup.m_node, bench, 10, 50,
false);
394 RegTestingSetup test_setup{};
395 const Config &config = test_setup.m_node.chainman->GetConfig();
396 benchReorg(config, test_setup.m_node, bench, 10, 500,
false);
401 RegTestingSetup test_setup{};
402 const Config &config = test_setup.m_node.chainman->GetConfig();
403 CTxIn utxo =
createUTXOs(config, 1, test_setup.m_node).back();
405 {oneInOneOutChain(config, std::move(utxo), 50)});
410 RegTestingSetup test_setup{};
411 const Config &config = test_setup.m_node.chainman->GetConfig();
412 CTxIn utxo =
createUTXOs(config, 1, test_setup.m_node).back();
414 {oneInOneOutChain(config, std::move(utxo), 500)});
420 RegTestingSetup test_setup{};
421 const Config &config = test_setup.m_node.chainman->GetConfig();
423 std::vector<std::vector<CTransactionRef>> chains;
424 constexpr int NChains = 2000;
425 const auto utxos =
createUTXOs(config, NChains, test_setup.m_node);
426 for (
int i = 0; i < NChains; ++i) {
435 RegTestingSetup test_setup{};
436 const Config &config = test_setup.m_node.chainman->GetConfig();
438 std::vector<std::vector<CTransactionRef>> chains;
439 constexpr int NChains = 2000;
440 const auto utxos =
createUTXOs(config, NChains, test_setup.m_node);
441 for (
int i = 0; i < NChains; ++i) {
static constexpr Amount SATOSHI
static constexpr Amount COIN
static void benchEviction(const Config &, benchmark::Bench &bench, const std::vector< std::vector< CTransactionRef > > &chains, bool revFee=true)
static void EvictChained50Tx(benchmark::Bench &bench)
Fill a mempool then evict 2000 x 50 1-input-1-output transactions, CTxMemPool version,...
static void Reorg10BlocksWith500TxChain(benchmark::Bench &bench)
Try to reorg a chain of depth 10 where each block has a 500 tx 1-input-1-output chain.
static void MempoolAcceptance50ChainedTxs(benchmark::Bench &bench)
Tests a chain of 50 1-input-1-output transactions.
static void MempoolAcceptance511TxTree(benchmark::Bench &bench)
Test a tree of 511 2-inputs-1-output transactions.
static void MempoolAcceptance63TxTree(benchmark::Bench &bench)
Test a tree of 63 2-inputs-1-output transactions.
static void EvictChained50TxRev(benchmark::Bench &bench)
Fill a mempool then evict 2000 x 50 1-input-1-output transactions, CTxMemPool version,...
static void Reorg10BlocksWith500TxChainSkipMempool(benchmark::Bench &bench)
Try to reorg a chain of depth 10 where each block has a 500 tx 1-input-1-output chain,...
static void MempoolAcceptance500ChainedTxs(benchmark::Bench &bench)
Tests a chain of 500 1-input-1-output transactions.
static void benchGenerateNewBlock(const Config &config, node::NodeContext &node, benchmark::Bench &bench, const std::vector< std::vector< CTransactionRef > > &chains)
static void GenerateBlock50ChainedTxs(benchmark::Bench &bench)
Generate a block with 50 1-input-1-output transactions.
static void Reorg10BlocksWith50TxChain(benchmark::Bench &bench)
Try to reorg a chain of depth 10 where each block has a 50 tx 1-input-1-output chain.
static void benchReorg(const Config &config, node::NodeContext &node, benchmark::Bench &bench, size_t reorgDepth, size_t chainSizePerBlock, bool includeMempoolTxRemoval)
Run benchmark that reorganizes blocks with one-input-one-output transaction chains in them.
static const CScript REDEEM_SCRIPT
This file contains benchmarks focusing on chained transactions in the mempool.
static std::vector< CTxIn > createUTXOs(const Config &config, size_t n, node::NodeContext &node)
Mine new utxos.
static void GenerateBlock500ChainedTxs(benchmark::Bench &bench)
Generate a block with 500 1-input-1-output transactions.
static std::vector< CTransactionRef > twoInOneOutTree(const Config &config, node::NodeContext &node, const size_t treeDepth)
Creates a tree of transactions with 2-inputs-1-output.
static std::vector< CTransactionRef > oneInOneOutChain(const Config &config, CTxIn utxo, const size_t chainLength)
Creates a chain of transactions with 1-input-1-output.
static const CScript SCRIPT_PUB_KEY
static void Reorg10BlocksWith50TxChainSkipMempool(benchmark::Bench &bench)
Try to reorg a chain of depth 10 where each block has a 50 tx 1-input-1-output chain,...
BENCHMARK(MempoolAcceptance50ChainedTxs)
static CTransactionRef toTx(const Config &config, CTxIn txin)
Create a transaction spending a coinbase utxo.
static const CScript SCRIPT_SIG
static void benchATMP(node::NodeContext &node, benchmark::Bench &bench, const std::vector< CTransactionRef > chainedTxs)
Run benchmark on AcceptToMemoryPool.
#define Assert(val)
Identity function.
The block chain is a tree shaped structure starting with the genesis block at the root,...
unsigned int nTx
Number of transactions in this block.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
A mutable version of CTransaction.
std::vector< CTxOut > vout
A reference to a CScript: the Hash160 of its serialization (see script.h)
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
RecursiveMutex cs
This mutex needs to be locked when accessing mapTx or other members that are guarded by it.
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(CTxMemPoolEntryRef entry) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
unsigned long size() const
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CChain m_chain
The current chain of blockheaders we consult and build on.
CTxMemPool * GetMempool()
bool InvalidateBlock(BlockValidationState &state, CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex
Mark a block as invalid.
void ResetBlockFailureFlags(CBlockIndex *pindex) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
Remove invalidity status from a block and its descendants.
bool ActivateBestChain(BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr, avalanche::Processor *const avalanche=nullptr, bool skip_checkblockindex=false) EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex
Find the best known block, and make it the tip of the block chain.
Main entry point to nanobench's benchmarking facility.
Bench & run(char const *benchmarkName, Op &&op)
Repeatedly calls op() based on the configuration, and performs measurements.
Bench & epochs(size_t numEpochs) noexcept
Controls number of epochs, the number of measurements to perform.
Bench & epochIterations(uint64_t numIters) noexcept
Sets exactly the number of iterations for each epoch.
Generate a new block, without valid proof-of-work.
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule).
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate.
static CTransactionRef MakeTransactionRef()
std::shared_ptr< const CTransaction > CTransactionRef
std::vector< uint8_t > ToByteVector(const T &in)
Validation result for a transaction evaluated by MemPoolAccept (single or package).
const ResultType m_result_type
Result type.
@ VALID
Fully validated, valid.
Options struct containing options for constructing a CTxMemPool.
int check_ratio
The ratio used to determine how often sanity checks will run.
NodeContext struct containing references to chain state and connection state.
int64_t GetTime()
DEPRECATED Use either ClockType::now() or Now<TimePointType>() if a cast is needed.
MempoolAcceptResult AcceptToMemoryPool(Chainstate &active_chainstate, const CTransactionRef &tx, int64_t accept_time, bool bypass_limits, bool test_accept, unsigned int heightOverride)
Try to add a transaction to the mempool.