| 304 | } // namespace |
| 305 | |
| 306 | FUZZ_TARGET(txgraph) |
| 307 | { |
| 308 | // This is a big simulation test for TxGraph, which performs a fuzz-derived sequence of valid |
| 309 | // operations on a TxGraph instance, as well as on a simpler (mostly) reimplementation (see |
| 310 | // SimTxGraph above), comparing the outcome of functions that return a result, and finally |
| 311 | // performing a full comparison between the two. |
| 312 | |
| 313 | SeedRandomStateForTest(SeedRand::ZEROS); |
| 314 | FuzzedDataProvider provider(buffer.data(), buffer.size()); |
| 315 | |
| 316 | /** Internal test RNG, used only for decisions which would require significant amount of data |
| 317 | * to be read from the provider, without realistically impacting test sensitivity, and for |
| 318 | * specialized test cases that are hard to perform more generically. */ |
| 319 | InsecureRandomContext rng(provider.ConsumeIntegral<uint64_t>()); |
| 320 | |
| 321 | /** Variable used whenever an empty SimTxObject is needed. */ |
| 322 | SimTxObject empty_ref; |
| 323 | |
| 324 | /** The maximum number of transactions per (non-oversized) cluster we will use in this |
| 325 | * simulation. */ |
| 326 | auto max_cluster_count = provider.ConsumeIntegralInRange<DepGraphIndex>(1, MAX_CLUSTER_COUNT_LIMIT); |
| 327 | /** The maximum total size of transactions in a (non-oversized) cluster. */ |
| 328 | auto max_cluster_size = provider.ConsumeIntegralInRange<uint64_t>(1, 0x3fffff * MAX_CLUSTER_COUNT_LIMIT); |
| 329 | /** The amount of work to consider a cluster acceptably linearized. */ |
| 330 | auto acceptable_cost = provider.ConsumeIntegralInRange<uint64_t>(0, 10000); |
| 331 | |
| 332 | /** The set of uint64_t "txid"s that have been assigned before. */ |
| 333 | std::set<uint64_t> assigned_txids; |
| 334 | |
| 335 | // Construct a real graph, and a vector of simulated graphs (main, and possibly staging). |
| 336 | auto fallback_order = [&](const TxGraph::Ref& a, const TxGraph::Ref& b) noexcept { |
| 337 | uint64_t txid_a = static_cast<const SimTxObject&>(a).m_txid; |
| 338 | uint64_t txid_b = static_cast<const SimTxObject&>(b).m_txid; |
| 339 | assert(assigned_txids.contains(txid_a)); |
| 340 | assert(assigned_txids.contains(txid_b)); |
| 341 | return txid_a <=> txid_b; |
| 342 | }; |
| 343 | auto real = MakeTxGraph( |
| 344 | /*max_cluster_count=*/max_cluster_count, |
| 345 | /*max_cluster_size=*/max_cluster_size, |
| 346 | /*acceptable_cost=*/acceptable_cost, |
| 347 | /*fallback_order=*/fallback_order); |
| 348 | |
| 349 | std::vector<SimTxGraph> sims; |
| 350 | sims.reserve(2); |
| 351 | sims.emplace_back(max_cluster_count, max_cluster_size); |
| 352 | |
| 353 | /** Struct encapsulating information about a BlockBuilder that's currently live. */ |
| 354 | struct BlockBuilderData |
| 355 | { |
| 356 | /** BlockBuilder object from real. */ |
| 357 | std::unique_ptr<TxGraph::BlockBuilder> builder; |
| 358 | /** The set of transactions marked as included in *builder. */ |
| 359 | SimTxGraph::SetType included; |
| 360 | /** The set of transactions marked as included or skipped in *builder. */ |
| 361 | SimTxGraph::SetType done; |
| 362 | /** The last chunk feerate returned by *builder. IsEmpty() if none yet. */ |
| 363 | FeePerWeight last_feerate; |
nothing calls this directly
no test coverage detected