mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-09 10:43:19 -05:00
[test util] to populate mempool with random transactions/packages
This commit is contained in:
parent
5374dfc4e3
commit
2118750631
2 changed files with 60 additions and 0 deletions
|
@ -43,6 +43,7 @@
|
||||||
#include <validationinterface.h>
|
#include <validationinterface.h>
|
||||||
#include <walletinitinterface.h>
|
#include <walletinitinterface.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
@ -357,6 +358,52 @@ CMutableTransaction TestChain100Setup::CreateValidMempoolTransaction(CTransactio
|
||||||
return mempool_txn;
|
return mempool_txn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<CTransactionRef> TestChain100Setup::PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit)
|
||||||
|
{
|
||||||
|
std::vector<CTransactionRef> mempool_transactions;
|
||||||
|
std::deque<std::pair<COutPoint, CAmount>> unspent_prevouts;
|
||||||
|
std::transform(m_coinbase_txns.begin(), m_coinbase_txns.end(), std::back_inserter(unspent_prevouts),
|
||||||
|
[](const auto& tx){ return std::make_pair(COutPoint(tx->GetHash(), 0), tx->vout[0].nValue); });
|
||||||
|
while (num_transactions > 0 && !unspent_prevouts.empty()) {
|
||||||
|
// The number of inputs and outputs are random, between 1 and 24.
|
||||||
|
CMutableTransaction mtx = CMutableTransaction();
|
||||||
|
const size_t num_inputs = det_rand.randrange(24) + 1;
|
||||||
|
CAmount total_in{0};
|
||||||
|
for (size_t n{0}; n < num_inputs; ++n) {
|
||||||
|
if (unspent_prevouts.empty()) break;
|
||||||
|
const auto& [prevout, amount] = unspent_prevouts.front();
|
||||||
|
mtx.vin.push_back(CTxIn(prevout, CScript()));
|
||||||
|
total_in += amount;
|
||||||
|
unspent_prevouts.pop_front();
|
||||||
|
}
|
||||||
|
const size_t num_outputs = det_rand.randrange(24) + 1;
|
||||||
|
// Approximately 1000sat "fee," equal output amounts.
|
||||||
|
const CAmount amount_per_output = (total_in - 1000) / num_outputs;
|
||||||
|
for (size_t n{0}; n < num_outputs; ++n) {
|
||||||
|
CScript spk = CScript() << CScriptNum(num_transactions + n);
|
||||||
|
mtx.vout.push_back(CTxOut(amount_per_output, spk));
|
||||||
|
}
|
||||||
|
CTransactionRef ptx = MakeTransactionRef(mtx);
|
||||||
|
mempool_transactions.push_back(ptx);
|
||||||
|
if (amount_per_output > 2000) {
|
||||||
|
// If the value is high enough to fund another transaction + fees, keep track of it so
|
||||||
|
// it can be used to build a more complex transaction graph. Insert randomly into
|
||||||
|
// unspent_prevouts for extra randomness in the resulting structures.
|
||||||
|
for (size_t n{0}; n < num_outputs; ++n) {
|
||||||
|
unspent_prevouts.push_back(std::make_pair(COutPoint(ptx->GetHash(), n), amount_per_output));
|
||||||
|
std::swap(unspent_prevouts.back(), unspent_prevouts[det_rand.randrange(unspent_prevouts.size())]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (submit) {
|
||||||
|
LOCK2(m_node.mempool->cs, cs_main);
|
||||||
|
LockPoints lp;
|
||||||
|
m_node.mempool->addUnchecked(CTxMemPoolEntry(ptx, 1000, 0, 1, false, 4, lp));
|
||||||
|
}
|
||||||
|
--num_transactions;
|
||||||
|
}
|
||||||
|
return mempool_transactions;
|
||||||
|
}
|
||||||
|
|
||||||
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction& tx) const
|
CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction& tx) const
|
||||||
{
|
{
|
||||||
return FromTx(MakeTransactionRef(tx));
|
return FromTx(MakeTransactionRef(tx));
|
||||||
|
|
|
@ -165,6 +165,19 @@ struct TestChain100Setup : public TestingSetup {
|
||||||
CAmount output_amount = CAmount(1 * COIN),
|
CAmount output_amount = CAmount(1 * COIN),
|
||||||
bool submit = true);
|
bool submit = true);
|
||||||
|
|
||||||
|
/** Create transactions spending from m_coinbase_txns. These transactions will only spend coins
|
||||||
|
* that exist in the current chain, but may be premature coinbase spends, have missing
|
||||||
|
* signatures, or violate some other consensus rules. They should only be used for testing
|
||||||
|
* mempool consistency. All transactions will have some random number of inputs and outputs
|
||||||
|
* (between 1 and 24). Transactions may or may not be dependent upon each other; if dependencies
|
||||||
|
* exit, every parent will always be somewhere in the list before the child so each transaction
|
||||||
|
* can be submitted in the same order they appear in the list.
|
||||||
|
* @param[in] submit When true, submit transactions to the mempool.
|
||||||
|
* When false, return them but don't submit them.
|
||||||
|
* @returns A vector of transactions that can be submitted to the mempool.
|
||||||
|
*/
|
||||||
|
std::vector<CTransactionRef> PopulateMempool(FastRandomContext& det_rand, size_t num_transactions, bool submit);
|
||||||
|
|
||||||
std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
|
std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
|
||||||
CKey coinbaseKey; // private/public key needed to spend coinbase transactions
|
CKey coinbaseKey; // private/public key needed to spend coinbase transactions
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue