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.
info.
m_tx->vout.size(); ++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;
119 mempool_opts.limits.descendant_size_vbytes = fuzzed_data_provider.
ConsumeIntegralInRange<
unsigned>(0, 202) * 1'000;
124 mempool_opts.check_ratio = 1;
125 mempool_opts.require_standard = fuzzed_data_provider.
ConsumeBool();
137 MockTime(fuzzed_data_provider, chainstate);
140 std::set<COutPoint> mempool_outpoints;
141 std::map<COutPoint, CAmount> outpoints_value;
142 for (
const auto& outpoint : g_outpoints_coinbase_init_mature) {
143 Assert(mempool_outpoints.insert(outpoint).second);
144 outpoints_value[outpoint] = 50 *
COIN;
147 auto outpoints_updater = std::make_shared<OutpointsUpdater>(mempool_outpoints);
151 MockedTxPool& tx_pool = *
static_cast<MockedTxPool*
>(&tx_pool_);
153 chainstate.SetMempool(&tx_pool);
157 Assert(!mempool_outpoints.empty());
159 std::vector<CTransactionRef> txs;
163 std::set<COutPoint> package_outpoints;
164 while (txs.size() < num_txs) {
169 bool last_tx = num_txs > 1 && txs.size() == num_txs - 1;
177 const auto num_in = last_tx ? package_outpoints.size() : fuzzed_data_provider.
ConsumeIntegralInRange<
int>(1, mempool_outpoints.size());
180 auto& outpoints = last_tx ? package_outpoints : mempool_outpoints;
182 Assert(!outpoints.empty());
185 for (
size_t i = 0; i < num_in; ++i) {
187 auto pop = outpoints.begin();
189 const auto outpoint = *pop;
190 outpoints.erase(pop);
192 amount_in += outpoints_value.at(outpoint);
196 const auto script_sig =
CScript{};
205 tx_mut.
vin.push_back(in);
209 bool dup_input = fuzzed_data_provider.
ConsumeBool();
211 tx_mut.
vin.push_back(tx_mut.
vin.back());
216 tx_mut.
vin.emplace_back();
220 const auto amount_out = (amount_in - amount_fee) / num_out;
221 for (
int i = 0; i < num_out; ++i) {
228 for (
const auto& in : tx->vin) {
233 for (
size_t i = 0; i < tx->vout.size(); ++i) {
234 package_outpoints.emplace(tx->GetHash(), i);
238 for (
size_t i = 0; i < tx->vout.size(); ++i) {
239 outpoints_value[
COutPoint(tx->GetHash(), i)] = tx->vout[i].nValue;
247 MockTime(fuzzed_data_provider, chainstate);
250 tx_pool.RollingFeeUpdate();
253 const auto& txid = fuzzed_data_provider.
ConsumeBool() ?
254 txs.back()->GetHash() :
255 PickValue(fuzzed_data_provider, mempool_outpoints).hash;
257 tx_pool.PrioritiseTransaction(txid.ToUint256(), delta);
261 std::set<CTransactionRef> added;
262 auto txr = std::make_shared<TransactionsDelta>(added);
264 const bool bypass_limits = fuzzed_data_provider.
ConsumeBool();
269 auto single_submit = txs.size() == 1 && fuzzed_data_provider.
ConsumeBool();
282 Assert(accepted != added.empty());
283 Assert(accepted == res.m_state.IsValid());
285 Assert(added.size() == 1);
286 Assert(txs.back() == *added.begin());
292 const bool expect_valid{result_package.m_state.IsValid()};
296 Assert(result_package.m_tx_results.size() == txs.size() || result_package.m_tx_results.empty());
int64_t CAmount
Amount in satoshis (Can be negative)
static constexpr CAmount COIN
The amount of satoshis in one BTC.
#define Assert(val)
Identity function.
int64_t GetMedianTimePast() const
CBlockIndex * Tip() const
Returns the index entry for the tip of this chain, or nullptr if none.
int Height() const
Return the maximal height in the chain.
An outpoint - a combination of a transaction hash and an index n into its vout.
Serialized script, used inside transaction inputs and outputs.
static const int32_t CURRENT_VERSION
An input of a transaction.
CScriptWitness scriptWitness
Only serialized through CTransaction.
CTxMemPool stores valid-according-to-the-current-best-chain transactions that may be included in the ...
Implement this to subscribe to events generated in validation and mempool.
virtual void TransactionRemovedFromMempool(const CTransactionRef &tx, MemPoolRemovalReason reason, uint64_t mempool_sequence)
Notifies listeners of a transaction leaving mempool.
virtual void TransactionAddedToMempool(const NewMempoolTransactionInfo &tx, uint64_t mempool_sequence)
Notifies listeners of a transaction having been added to mempool.
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.
CCoinsViewCache & CoinsTip() EXCLUSIVE_LOCKS_REQUIRED(
T ConsumeIntegralInRange(T min, T max)
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.
#define LIMITED_WHILE(condition, limit)
Can be used to limit a theoretically unbounded loop.
MemPoolRemovalReason
Reason why a transaction was removed from the mempool, this is passed to the notification signal.
@ PCKG_POLICY
The package itself is invalid (e.g. too many transactions).
unsigned int nBytesPerSigOp
static CTransactionRef MakeTransactionRef(Tx &&txIn)
std::shared_ptr< const CTransaction > CTransactionRef
A mutable version of CTransaction.
std::vector< CTxOut > vout
std::vector< std::vector< unsigned char > > stack
Testing setup that configures a complete environment.
const CTransactionRef m_tx
int64_t ancestor_count
The maximum allowed number of transactions in a package including the entry and its ancestors.
Options struct containing options for constructing a CTxMemPool.
NodeContext struct containing references to chain state and connection state.
#define WITH_LOCK(cs, code)
Run code while locking a mutex.
uint32_t ConsumeSequence(FuzzedDataProvider &fuzzed_data_provider) noexcept
int64_t ConsumeTime(FuzzedDataProvider &fuzzed_data_provider, const std::optional< int64_t > &min, const std::optional< int64_t > &max) noexcept
auto & PickValue(FuzzedDataProvider &fuzzed_data_provider, Collection &col)
COutPoint MineBlock(const NodeContext &node, const CScript &coinbase_scriptPubKey)
Returns the generated coin.
static const std::vector< std::vector< uint8_t > > P2WSH_EMPTY_TRUE_STACK
static const std::vector< std::vector< uint8_t > > P2WSH_EMPTY_TWO_STACK
static const CScript P2WSH_EMPTY
CTxMemPool::Options MemPoolOptionsForTest(const NodeContext &node)
std::optional< std::string > CheckPackageMempoolAcceptResult(const Package &txns, const PackageMempoolAcceptResult &result, bool expect_valid, const CTxMemPool *mempool)
Check expected properties for every PackageMempoolAcceptResult, regardless of value.
#define EXCLUSIVE_LOCKS_REQUIRED(...)
void SetMockTime(int64_t nMockTimeIn)
DEPRECATED Use SetMockTime with chrono type.
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.
PackageMempoolAcceptResult ProcessNewPackage(Chainstate &active_chainstate, CTxMemPool &pool, const Package &package, bool test_accept)
Validate (and maybe submit) a package to the mempool.
void UnregisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Unregister subscriber.
void SyncWithValidationInterfaceQueue()
This is a synonym for the following, which asserts certain locks are not held: std::promise<void> pro...
void RegisterSharedValidationInterface(std::shared_ptr< CValidationInterface > callbacks)
Register subscriber.