15 #include <validation.h>
17 #include <test/util/mining.h>
18 #include <test/util/setup_common.h>
39 std::vector<CTxIn> utxos;
42 for (
size_t i = 0; i < n; ++i) {
56 tx.
vin.emplace_back(txin);
63 static 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;
120 chain.push_back(txref);
124 queue.emplace(txref);
126 assert(chain.size() == txs);
133 const std::vector<CTransactionRef> chainedTxs) {
135 Chainstate &activeChainState = chainman->ActiveChainstate();
138 assert(mempool.size() == 0);
142 for (
const auto &tx : chainedTxs) {
160 size_t chainSizePerBlock,
bool includeMempoolTxRemoval) {
162 std::vector<std::vector<CTransactionRef>> chains;
163 for (
auto &utxo : utxos) {
169 Chainstate &activeChainState = chainman->ActiveChainstate();
173 assert(tipBeforeInvalidate !=
nullptr);
178 assert(mempool.size() == 0);
181 TestMemPoolEntryHelper entry;
183 for (
const auto &chain : chains) {
185 entry.spendsCoinbase =
true;
187 for (
const auto &tx : chain) {
188 mempool.addUnchecked(entry.FromTx(tx));
191 entry.spendsCoinbase =
false;
194 assert(mempool.size() == chain.size());
196 assert(mempool.size() == 0);
201 if (blockToInvalidate ==
nullptr) {
202 blockToInvalidate = activeChainState.
m_chain.
Tip();
219 assert(mempool.size() == reorgDepth * chainSizePerBlock);
221 if (!includeMempoolTxRemoval) {
237 assert(mempool.size() == 0);
244 const std::vector<std::vector<CTransactionRef>> &chains) {
245 TestMemPoolEntryHelper entry;
249 Chainstate &activeChainState = chainman->ActiveChainstate();
254 for (
const auto &chain : chains) {
255 entry.spendsCoinbase =
true;
257 for (
const auto &tx : chain) {
258 mempool.addUnchecked(entry.FromTx(tx));
261 entry.spendsCoinbase =
false;
265 assert(mempool.size() == txCount);
274 assert(blocktemplate->block.vtx.size() == txCount + 1);
280 const std::vector<std::vector<CTransactionRef>> &chains,
281 bool revFee =
true) {
282 std::list<CTxMemPool> pools;
292 pools.emplace_back();
294 TestMemPoolEntryHelper entry;
301 for (
const auto &chain : chains) {
302 entry.spendsCoinbase =
true;
304 entry.nFee += int64_t(chain.size()) *
SATOSHI;
307 for (
const auto &tx : chain) {
309 entry.nFee += feeBump;
312 entry.spendsCoinbase =
false;
316 entry.nFee += int64_t(chain.size()) *
SATOSHI;
322 auto it = pools.begin();
325 assert(it != pools.end());
328 while (
auto prevSize = pool.size()) {
329 pool.TrimToSize(pool.DynamicMemoryUsage() * 99 / 100);
330 assert(pool.size() < prevSize);
337 RegTestingSetup test_setup{};
340 config,
createUTXOs(config, 1, test_setup.m_node).back(), 50);
341 benchATMP(config, test_setup.m_node, bench, chainedTxs);
346 RegTestingSetup test_setup{};
349 config,
createUTXOs(config, 1, test_setup.m_node).back(), 500);
350 benchATMP(config, test_setup.m_node, bench, chainedTxs);
355 RegTestingSetup test_setup{};
357 const std::vector<CTransactionRef> chainedTxs =
359 assert(chainedTxs.size() == 63);
360 benchATMP(config, test_setup.m_node, bench, chainedTxs);
365 RegTestingSetup test_setup{};
367 const std::vector<CTransactionRef> chainedTxs =
369 assert(chainedTxs.size() == 511);
370 benchATMP(config, test_setup.m_node, bench, chainedTxs);
376 RegTestingSetup test_setup{};
378 benchReorg(config, test_setup.m_node, bench, 10, 50,
true);
384 RegTestingSetup test_setup{};
386 benchReorg(config, test_setup.m_node, bench, 10, 500,
true);
393 RegTestingSetup test_setup{};
395 benchReorg(config, test_setup.m_node, bench, 10, 50,
false);
402 RegTestingSetup test_setup{};
404 benchReorg(config, test_setup.m_node, bench, 10, 500,
false);
409 RegTestingSetup test_setup{};
413 {oneInOneOutChain(config, std::move(utxo), 50)});
418 RegTestingSetup test_setup{};
422 {oneInOneOutChain(config, std::move(utxo), 500)});
428 RegTestingSetup test_setup{};
431 std::vector<std::vector<CTransactionRef>> chains;
432 constexpr
int NChains = 2000;
433 const auto utxos =
createUTXOs(config, NChains, test_setup.m_node);
434 for (
int i = 0; i < NChains; ++i) {
443 RegTestingSetup test_setup{};
446 std::vector<std::vector<CTransactionRef>> chains;
447 constexpr
int NChains = 2000;
448 const auto utxos =
createUTXOs(config, NChains, test_setup.m_node);
449 for (
int i = 0; i < NChains; ++i) {
static constexpr Amount SATOSHI
static constexpr Amount COIN
RecursiveMutex cs_main
Global state.
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 std::vector< CTxIn > createUTXOs(const Config &config, size_t n, node::NodeContext &node)
Mine new utxos.
static void benchATMP(const Config &config, node::NodeContext &node, benchmark::Bench &bench, const std::vector< CTransactionRef > chainedTxs)
Run benchmark on AcceptToMemoryPool.
static void benchGenerateNewBlock(const Config &config, node::NodeContext &node, benchmark::Bench &bench, const std::vector< std::vector< CTransactionRef >> &chains)
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 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 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 benchEviction(const Config &, benchmark::Bench &bench, const std::vector< std::vector< CTransactionRef >> &chains, bool revFee=true)
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 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 REDEEM_SCRIPT
This file contains benchmarks focusing on chained transactions in the mempool.
static void GenerateBlock500ChainedTxs(benchmark::Bench &bench)
Generate a block with 500 1-input-1-output transactions.
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
#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
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
A reference to a CScript: the Hash160 of its serialization (see script.h)
An input of a transaction.
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.
unsigned long size() const
void check(const CCoinsViewCache &active_coins_tip, int64_t spendheight) const EXCLUSIVE_LOCKS_REQUIRED(void addUnchecked(const CTxMemPoolEntry &entry) EXCLUSIVE_LOCKS_REQUIRED(cs
If sanity-checking is turned on, check makes sure the pool is consistent (does not contain two transa...
Chainstate stores and provides an API to update our local knowledge of the current best chain.
CTxMemPool * GetMempool()
CChain m_chain
The current chain of blockheaders we consult and build on.
bool InvalidateBlock(const Config &config, BlockValidationState &state, CBlockIndex *pindex) LOCKS_EXCLUDED(cs_main) 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(const Config &config, BlockValidationState &state, std::shared_ptr< const CBlock > pblock=nullptr) EXCLUSIVE_LOCKS_REQUIRED(!m_chainstate_mutex) LOCKS_EXCLUDED(cs_main)
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 & epochIterations(uint64_t numIters) noexcept
Sets exactly the number of iterations for each epoch.
Bench & epochs(size_t numEpochs) noexcept
Controls number of epochs, the number of measurements to perform.
Generate a new block, without valid proof-of-work.
std::unique_ptr< CBlockTemplate > CreateNewBlock(const CScript &scriptPubKeyIn)
Construct a new block template with coinbase to scriptPubKeyIn.
const Config & GetConfig()
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule).
static CTransactionRef MakeTransactionRef()
std::shared_ptr< const CTransaction > CTransactionRef
std::vector< uint8_t > ToByteVector(const T &in)
Validation result for a single transaction mempool acceptance.
const ResultType m_result_type
@ VALID
Fully validated, valid.
NodeContext struct containing references to chain state and connection state.
T GetTime()
Return system time (or mocked time, if set)
MempoolAcceptResult AcceptToMemoryPool(const Config &config, 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.