MCPcopy Create free account
hub / github.com/bitcoin/bitcoin / MinimizeStep

Method MinimizeStep

src/cluster_linearize.h:1357–1447  ·  view source on GitHub ↗

Try to reduce a chunk's size. Returns false if all chunks are minimal, true otherwise. */

Source from the content-addressed store, hash-verified

1355
1356 /** Try to reduce a chunk's size. Returns false if all chunks are minimal, true otherwise. */
1357 bool MinimizeStep() noexcept
1358 {
1359 // If the queue of potentially-non-minimal chunks is empty, we are done.
1360 if (m_nonminimal_chunks.empty()) return false;
1361 m_cost.MinimizeStepBegin();
1362 // Pop an entry from the potentially-non-minimal chunk queue.
1363 auto [chunk_idx, pivot_idx, flags] = m_nonminimal_chunks.front();
1364 m_nonminimal_chunks.pop_front();
1365 auto& chunk_info = m_set_info[chunk_idx];
1366 /** Whether to move the pivot down rather than up. */
1367 bool move_pivot_down = flags & 1;
1368 /** Whether this is already the second stage. */
1369 bool second_stage = flags & 2;
1370
1371 // Find a random dependency whose top and bottom set feerates are equal, and which has
1372 // pivot in bottom set (if move_pivot_down) or in top set (if !move_pivot_down).
1373 std::pair<TxIdx, TxIdx> candidate_dep;
1374 uint64_t candidate_tiebreak{0};
1375 bool have_any = false;
1376 // Iterate over all transactions.
1377 for (auto tx_idx : chunk_info.transactions) {
1378 const auto& tx_data = m_tx_data[tx_idx];
1379 // Iterate over all active child dependencies of the transaction.
1380 for (auto child_idx : tx_data.active_children) {
1381 const auto& dep_top_info = m_set_info[tx_data.dep_top_idx[child_idx]];
1382 // Skip if this dependency does not have equal top and bottom set feerates. Note
1383 // that the top cannot have higher feerate than the bottom, or OptimizeSteps would
1384 // have dealt with it.
1385 if (ByRatio{dep_top_info.feerate} < ByRatio{chunk_info.feerate}) continue;
1386 have_any = true;
1387 // Skip if this dependency does not have pivot in the right place.
1388 if (move_pivot_down == dep_top_info.transactions[pivot_idx]) continue;
1389 // Remember this as our chosen dependency if it has a better tiebreak.
1390 uint64_t tiebreak = m_rng.rand64() | 1;
1391 if (tiebreak > candidate_tiebreak) {
1392 candidate_tiebreak = tiebreak;
1393 candidate_dep = {tx_idx, child_idx};
1394 }
1395 }
1396 }
1397 m_cost.MinimizeStepMid(/*num_txns=*/chunk_info.transactions.Count());
1398 // If no dependencies have equal top and bottom set feerate, this chunk is minimal.
1399 if (!have_any) return true;
1400 // If all found dependencies have the pivot in the wrong place, try moving it in the other
1401 // direction. If this was the second stage already, we are done.
1402 if (candidate_tiebreak == 0) {
1403 // Switch to other direction, and to second phase.
1404 flags ^= 3;
1405 if (!second_stage) m_nonminimal_chunks.emplace_back(chunk_idx, pivot_idx, flags);
1406 return true;
1407 }
1408
1409 // Otherwise, deactivate the dependency that was found.
1410 auto [parent_chunk_idx, child_chunk_idx] = Deactivate(candidate_dep.first, candidate_dep.second);
1411 // Determine if there is a dependency from the new bottom to the new top (opposite from the
1412 // dependency that was just deactivated).
1413 auto& parent_reachable = m_reachable[parent_chunk_idx].first;
1414 auto& child_chunk_txn = m_set_info[child_chunk_idx].transactions;

Callers 2

LinearizeFunction · 0.80
FUZZ_TARGETFunction · 0.80

Calls 13

MinimizeStepBeginMethod · 0.80
MinimizeStepMidMethod · 0.80
MinimizeStepEndMethod · 0.80
randboolMethod · 0.80
emptyMethod · 0.45
frontMethod · 0.45
pop_frontMethod · 0.45
rand64Method · 0.45
CountMethod · 0.45
emplace_backMethod · 0.45
OverlapsMethod · 0.45
backMethod · 0.45

Tested by 1

FUZZ_TARGETFunction · 0.64