| 117 | } |
| 118 | |
| 119 | void Finish(FuzzedDataProvider& fuzzed_data_provider, MockedTxPool& tx_pool, Chainstate& chainstate) |
| 120 | { |
| 121 | WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1)); |
| 122 | { |
| 123 | BlockCreateOptions options{ |
| 124 | .block_min_fee_rate = CFeeRate{ConsumeMoney(fuzzed_data_provider, /*max=*/COIN)}, |
| 125 | .block_max_weight = fuzzed_data_provider.ConsumeIntegralInRange<uint64_t>(DEFAULT_BLOCK_RESERVED_WEIGHT, MAX_BLOCK_WEIGHT), |
| 126 | }; |
| 127 | auto assembler = BlockAssembler{chainstate, &tx_pool, options}; |
| 128 | auto block_template = assembler.CreateNewBlock(); |
| 129 | Assert(block_template->block.vtx.size() >= 1); |
| 130 | |
| 131 | // Try updating the mempool for this block, as though it were mined. |
| 132 | LOCK2(::cs_main, tx_pool.cs); |
| 133 | tx_pool.removeForBlock(block_template->block.vtx, chainstate.m_chain.Height() + 1); |
| 134 | |
| 135 | // Now try to add those transactions back, as though a reorg happened. |
| 136 | std::vector<Txid> hashes_to_update; |
| 137 | for (const auto& tx : block_template->block.vtx) { |
| 138 | const auto res = AcceptToMemoryPool(chainstate, tx, GetTime(), true, /*test_accept=*/false); |
| 139 | if (res.m_result_type == MempoolAcceptResult::ResultType::VALID) { |
| 140 | hashes_to_update.push_back(tx->GetHash()); |
| 141 | } else { |
| 142 | tx_pool.removeRecursive(*tx, MemPoolRemovalReason::REORG); |
| 143 | } |
| 144 | } |
| 145 | tx_pool.UpdateTransactionsFromBlock(hashes_to_update); |
| 146 | } |
| 147 | const auto info_all = tx_pool.infoAll(); |
| 148 | if (!info_all.empty()) { |
| 149 | const auto& tx_to_remove = *PickValue(fuzzed_data_provider, info_all).tx; |
| 150 | WITH_LOCK(tx_pool.cs, tx_pool.removeRecursive(tx_to_remove, MemPoolRemovalReason::BLOCK /* dummy */)); |
| 151 | assert(tx_pool.size() < info_all.size()); |
| 152 | } |
| 153 | |
| 154 | if (fuzzed_data_provider.ConsumeBool()) { |
| 155 | // Try eviction |
| 156 | LOCK2(::cs_main, tx_pool.cs); |
| 157 | tx_pool.TrimToSize(fuzzed_data_provider.ConsumeIntegralInRange<size_t>(0U, tx_pool.DynamicMemoryUsage() * 2)); |
| 158 | } |
| 159 | if (fuzzed_data_provider.ConsumeBool()) { |
| 160 | // Try expiry |
| 161 | LOCK2(::cs_main, tx_pool.cs); |
| 162 | tx_pool.Expire(GetMockTime() - std::chrono::seconds(fuzzed_data_provider.ConsumeIntegral<uint32_t>())); |
| 163 | } |
| 164 | WITH_LOCK(::cs_main, tx_pool.check(chainstate.CoinsTip(), chainstate.m_chain.Height() + 1)); |
| 165 | g_setup->m_node.validation_signals->SyncWithValidationInterfaceQueue(); |
| 166 | } |
| 167 | |
| 168 | void MockTime(FuzzedDataProvider& fuzzed_data_provider, const Chainstate& chainstate) |
| 169 | { |
no test coverage detected