| 122 | } |
| 123 | |
| 124 | FUZZ_TARGET_INIT(tx_pool_standard, initialize_tx_pool) |
| 125 | { |
| 126 | FuzzedDataProvider fuzzed_data_provider(buffer.data(), buffer.size()); |
| 127 | const auto& node = g_setup->m_node; |
| 128 | auto& chainstate{static_cast<DummyChainState&>(node.chainman->ActiveChainstate())}; |
| 129 | |
| 130 | MockTime(fuzzed_data_provider, chainstate); |
| 131 | SetMempoolConstraints(*node.args, fuzzed_data_provider); |
| 132 | |
| 133 | // All RBF-spendable outpoints |
| 134 | std::set<COutPoint> outpoints_rbf; |
| 135 | // All outpoints counting toward the total supply (subset of outpoints_rbf) |
| 136 | std::set<COutPoint> outpoints_supply; |
| 137 | for (const auto& outpoint : g_outpoints_coinbase_init_mature) { |
| 138 | Assert(outpoints_supply.insert(outpoint).second); |
| 139 | } |
| 140 | outpoints_rbf = outpoints_supply; |
| 141 | |
| 142 | // The sum of the values of all spendable outpoints |
| 143 | constexpr CAmount SUPPLY_TOTAL{COINBASE_MATURITY * 50 * COIN}; |
| 144 | |
| 145 | CTxMemPool tx_pool_{/*estimator=*/nullptr, /*check_ratio=*/1}; |
| 146 | MockedTxPool& tx_pool = *static_cast<MockedTxPool*>(&tx_pool_); |
| 147 | |
| 148 | chainstate.SetMempool(&tx_pool); |
| 149 | |
| 150 | // Helper to query an amount |
| 151 | const CCoinsViewMemPool amount_view{WITH_LOCK(::cs_main, return &chainstate.CoinsTip()), tx_pool}; |
| 152 | const auto GetAmount = [&](const COutPoint& outpoint) { |
| 153 | Coin c; |
| 154 | Assert(amount_view.GetCoin(outpoint, c)); |
| 155 | return c.out.nValue.GetAmount(); |
| 156 | }; |
| 157 | |
| 158 | LIMITED_WHILE(fuzzed_data_provider.ConsumeBool(), 300) |
| 159 | { |
| 160 | { |
| 161 | // Total supply is the mempool fee + all outpoints |
| 162 | CAmount supply_now{WITH_LOCK(tx_pool.cs, return tx_pool.GetTotalFee())}; |
| 163 | for (const auto& op : outpoints_supply) { |
| 164 | supply_now += GetAmount(op); |
| 165 | } |
| 166 | Assert(supply_now == SUPPLY_TOTAL); |
| 167 | } |
| 168 | Assert(!outpoints_supply.empty()); |
| 169 | |
| 170 | // Create transaction to add to the mempool |
| 171 | const CTransactionRef tx = [&] { |
| 172 | CMutableTransaction tx_mut; |
| 173 | tx_mut.nVersion = CTransaction::CURRENT_VERSION; |
| 174 | tx_mut.nLockTime = fuzzed_data_provider.ConsumeBool() ? 0 : fuzzed_data_provider.ConsumeIntegral<uint32_t>(); |
| 175 | const auto num_in = fuzzed_data_provider.ConsumeIntegralInRange<int>(1, outpoints_rbf.size()); |
| 176 | const auto num_out = fuzzed_data_provider.ConsumeIntegralInRange<int>(1, outpoints_rbf.size() * 2); |
| 177 | |
| 178 | CAmount amount_in{0}; |
| 179 | for (int i = 0; i < num_in; ++i) { |
| 180 | // Pop random outpoint |
| 181 | auto pop = outpoints_rbf.begin(); |
nothing calls this directly
no test coverage detected