MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / PopulateMempool

Method PopulateMempool

src/test/util/setup_common.cpp:576–639  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

574}
575
576std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit)
577{
578 std::vector<CTransactionRef> mempool_transactions;
579 std::deque<std::pair<COutPoint, CAmount>> unspent_prevouts, undo_info;
580 std::transform(m_coinbase_txns.begin(), m_coinbase_txns.end(), std::back_inserter(unspent_prevouts),
581 [](const auto& tx){ return std::make_pair(COutPoint(tx->GetHash(), 0), tx->vout[0].nValue); });
582 while (num_transactions > 0 && !unspent_prevouts.empty()) {
583 // The number of inputs and outputs are randomly chosen, between 1-5
584 // and 1-25 respectively.
585 CMutableTransaction mtx = CMutableTransaction();
586 const size_t num_inputs = det_rand.randrange(5) + 1;
587 CAmount total_in{0};
588 for (size_t n{0}; n < num_inputs; ++n) {
589 if (unspent_prevouts.empty()) break;
590 const auto& [prevout, amount] = unspent_prevouts.front();
591 undo_info.emplace_back(prevout, amount);
592 mtx.vin.emplace_back(prevout, CScript());
593 total_in += amount;
594 unspent_prevouts.pop_front();
595 }
596 const size_t num_outputs = det_rand.randrange(25) + 1;
597 const CAmount fee = 100 * det_rand.randrange(30);
598 const CAmount amount_per_output = (total_in - fee) / num_outputs;
599 for (size_t n{0}; n < num_outputs; ++n) {
600 CScript spk = CScript() << CScriptNum(num_transactions + n);
601 mtx.vout.emplace_back(amount_per_output, spk);
602 }
603 CTransactionRef ptx = MakeTransactionRef(mtx);
604 bool success{true};
605 if (submit) {
606 LOCK2(cs_main, m_node.mempool->cs);
607 LockPoints lp;
608 auto changeset = m_node.mempool->GetChangeSet();
609 changeset->StageAddition(ptx, /*fee=*/(total_in - num_outputs * amount_per_output),
610 /*time=*/0, /*entry_height=*/1, /*entry_sequence=*/0,
611 /*spends_coinbase=*/false, /*sigops_cost=*/4, lp);
612 if (changeset->CheckMemPoolPolicyLimits()) {
613 changeset->Apply();
614 --num_transactions;
615 } else {
616 success = false;
617 // Add the inputs back to unspent prevouts
618 for (const auto& [prevout, amount] : undo_info) {
619 unspent_prevouts.emplace_back(prevout, amount);
620 std::swap(unspent_prevouts.back(), unspent_prevouts[det_rand.randrange(unspent_prevouts.size())]);
621 }
622 }
623 }
624 if (success) {
625 mempool_transactions.push_back(ptx);
626 if (amount_per_output > 3000) {
627 // If the value is high enough to fund another transaction + fees, keep track of it so
628 // it can be used to build a more complex transaction graph. Insert randomly into
629 // unspent_prevouts for extra randomness in the resulting structures.
630 for (size_t n{0}; n < num_outputs; ++n) {
631 unspent_prevouts.emplace_back(COutPoint(ptx->GetHash(), n), amount_per_output);
632 std::swap(unspent_prevouts.back(), unspent_prevouts[det_rand.randrange(unspent_prevouts.size())]);
633 }

Callers 2

MempoolCheckFunction · 0.80

Calls 15

MakeTransactionRefFunction · 0.85
randrangeMethod · 0.80
StageAdditionMethod · 0.80
COutPointClass · 0.70
CScriptClass · 0.70
CMutableTransactionClass · 0.50
CScriptNumClass · 0.50
beginMethod · 0.45
endMethod · 0.45
GetHashMethod · 0.45
emptyMethod · 0.45

Tested by

no test coverage detected