26 std::vector<COutPoint> g_outpoints_coinbase_init_mature;
32 lastRollingFeeUpdate =
GetTime();
33 blockSinceLastRollingFeeBump =
true;
37 void initialize_tx_pool()
39 static const auto testing_setup = MakeNoLogFileContext<const TestingSetup>();
40 g_setup = testing_setup.get();
46 g_outpoints_coinbase_init_mature.push_back(prevout);
53 std::set<COutPoint>& m_mempool_outpoints;
55 explicit OutpointsUpdater(std::set<COutPoint>& r)
56 : m_mempool_outpoints{r} {}
63 for (uint32_t index{0}; index < tx->vout.size(); ++index) {
64 m_mempool_outpoints.insert(
COutPoint{tx->GetHash(), index});
71 for (
const auto& input : tx->vin) {
73 m_mempool_outpoints.insert(input.prevout);
76 for (uint32_t index{0}; index < tx->vout.size(); ++index) {
77 m_mempool_outpoints.erase(
COutPoint{tx->GetHash(), index});
83 std::set<CTransactionRef>& m_added;
85 explicit TransactionsDelta(std::set<CTransactionRef>& a)
103 const auto time =
ConsumeTime(fuzzed_data_provider,
105 std::numeric_limits<decltype(chainstate.
m_chain.
Tip()->
nTime)>::max());
117 mempool_opts.limits.ancestor_size_vbytes = fuzzed_data_provider.
ConsumeIntegralInRange<
unsigned>(0, 202) * 1
'000; 118 mempool_opts.limits.descendant_count = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 50); 119 mempool_opts.limits.descendant_size_vbytes = fuzzed_data_provider.ConsumeIntegralInRange<unsigned>(0, 202) * 1'000;
124 mempool_opts.estimator =
nullptr;
125 mempool_opts.check_ratio = 1;
126 mempool_opts.require_standard = fuzzed_data_provider.
ConsumeBool();
135 const auto&
node = g_setup->m_node;
138 MockTime(fuzzed_data_provider, chainstate);
141 std::set<COutPoint> mempool_outpoints;
142 std::map<COutPoint, CAmount> outpoints_value;
143 for (
const auto& outpoint : g_outpoints_coinbase_init_mature) {
144 Assert(mempool_outpoints.insert(outpoint).second);
145 outpoints_value[outpoint] = 50 *
COIN;
148 auto outpoints_updater = std::make_shared<OutpointsUpdater>(mempool_outpoints);
152 MockedTxPool& tx_pool = *
static_cast<MockedTxPool*
>(&tx_pool_);
154 chainstate.SetMempool(&tx_pool);
158 Assert(!mempool_outpoints.empty());
160 std::vector<CTransactionRef> txs;
164 std::set<COutPoint> package_outpoints;
165 while (txs.size() < num_txs) {
170 bool last_tx = num_txs > 1 && txs.size() == num_txs - 1;
178 const auto num_in = last_tx ? package_outpoints.size() : fuzzed_data_provider.
ConsumeIntegralInRange<
int>(1, mempool_outpoints.size());
181 auto& outpoints = last_tx ? package_outpoints : mempool_outpoints;
183 Assert(!outpoints.empty());
186 for (
size_t i = 0; i < num_in; ++i) {
188 auto pop = outpoints.begin();
190 const auto outpoint = *pop;
191 outpoints.erase(pop);
193 amount_in += outpoints_value.at(outpoint);
197 const auto script_sig =
CScript{};
205 tx_mut.
vin.push_back(in);
208 const auto amount_out = (amount_in - amount_fee) / num_out;
209 for (
int i = 0; i < num_out; ++i) {
216 for (
const auto& in : tx->vin) {
220 for (
size_t i = 0; i < tx->vout.size(); ++i) {
221 package_outpoints.emplace(tx->GetHash(), i);
225 for (
size_t i = 0; i < tx->vout.size(); ++i) {
226 outpoints_value[
COutPoint(tx->GetHash(), i)] = tx->vout[i].nValue;
234 MockTime(fuzzed_data_provider, chainstate);
237 tx_pool.RollingFeeUpdate();
240 const auto& txid = fuzzed_data_provider.
ConsumeBool() ?
241 txs.back()->GetHash() :
242 PickValue(fuzzed_data_provider, mempool_outpoints).hash;
244 tx_pool.PrioritiseTransaction(txid, delta);
248 std::set<CTransactionRef> added;
249 auto txr = std::make_shared<TransactionsDelta>(added);
251 const bool bypass_limits = fuzzed_data_provider.
ConsumeBool();
256 auto single_submit = txs.size() == 1 && fuzzed_data_provider.
ConsumeBool();
263 auto it = result_package.m_tx_results.find(txs.back()->GetWitnessHash());
264 Assert(it != result_package.m_tx_results.end());
278 Assert(accepted != added.empty());
279 Assert(accepted == res.m_state.IsValid());
281 Assert(added.size() == 1);
282 Assert(txs.back() == *added.begin());
286 Assert(result_package.m_tx_results.size() == txs.size() || result_package.m_tx_results.empty());
std::shared_ptr< const CTransaction > CTransactionRef
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
virtual void TransactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence)
Notifies listeners of a transaction leaving mempool.
The package itself is invalid (e.g. too many transactions).
static const CScript P2WSH_OP_TRUE
CScriptWitness scriptWitness
Only serialized through CTransaction.
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal...
int Height() const
Return the maximal height in the chain.
static const int COINBASE_MATURITY
Coinbase transaction outputs can only be spent after this number of new blocks (network rule) ...
std::vector< std::vector< unsigned char > > stack
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.
CChain m_chain
The current chain of blockheaders we consult and build on.
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
Implement this to subscribe to events generated in validation.
int64_t CAmount
Amount in satoshis (Can be negative)
MempoolAcceptResult AcceptToMemoryPool(Chainstate &active_chainstate, const CTransactionRef &tx, int64_t accept_time, bool bypass_limits, bool test_accept) EXCLUSIVE_LOCKS_REQUIRED(
Try to add a transaction to the mempool.
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
NodeContext struct containing references to chain state and connection state.
Chainstate stores and provides an API to update our local knowledge of the current best chain...
An input of a transaction.
static const std::vector< uint8_t > WITNESS_STACK_ELEM_OP_TRUE
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept)
Validate (and maybe submit) a package to the mempool.
An outpoint - a combination of a transaction hash and an index n into its vout.
std::vector< CTxOut > vout
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
int64_t GetMedianTimePast() const
static CTransactionRef MakeTransactionRef(Tx &&txIn)
COutPoint MineBlock(const NodeContext &node, const CScript &coinbase_scriptPubKey)
Returns the generated coin.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
unsigned int nBytesPerSigOp
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Serialized script, used inside transaction inputs and outputs.
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
virtual void TransactionAddedToMempool(const CTransactionRef &tx, uint64_t mempool_sequence)
Notifies listeners of a transaction having been added to mempool.
A mutable version of CTransaction.
Options struct containing options for constructing a CTxMemPool.
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
static const int32_t CURRENT_VERSION
int64_t ancestor_count
The maximum allowed number of transactions in a package including the entry and its ancestors...
T ConsumeIntegralInRange(T min, T max)
int64_t GetTime()
DEPRECATED, see GetTime.
RecursiveMutex cs_main
Mutex to guard access to validation specific variables, such as reading or changing the chainstate...
Testing setup that configures a complete environment.
#define Assert(val)
Identity function.
uint32_t ConsumeSequence(FuzzedDataProvider &fuzzed_data_provider) noexcept
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
static constexpr CAmount COIN
The amount of satoshis in one BTC.