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

Method GetLinearization

src/cluster_linearize.h:1465–1605  ·  view source on GitHub ↗

Construct a topologically-valid linearization from the current forest state. Must be * topological. fallback_order is a comparator that defines a strong order for DepGraphIndexes * in this cluster, used to order equal-feerate transactions and chunks. * * Specifically, the resulting order consists of: * - The chunks of the current SFL state, sorted by (in decreasing order

Source from the content-addressed store, hash-verified

1463 * - the lowest transaction, by fallback_order, first
1464 */
1465 std::vector<DepGraphIndex> GetLinearization(const StrongComparator<DepGraphIndex> auto& fallback_order) noexcept
1466 {
1467 m_cost.GetLinearizationBegin();
1468 /** The output linearization. */
1469 std::vector<DepGraphIndex> ret;
1470 ret.reserve(m_set_info.size());
1471 /** A heap with all chunks (by set index) that can currently be included, sorted by
1472 * chunk feerate (high to low), chunk size (small to large), and by least maximum element
1473 * according to the fallback order (which is the second pair element). */
1474 std::vector<std::pair<SetIdx, TxIdx>> ready_chunks;
1475 /** For every chunk, indexed by SetIdx, the number of unmet dependencies the chunk has on
1476 * other chunks (not including dependencies within the chunk itself). */
1477 std::vector<TxIdx> chunk_deps(m_set_info.size(), 0);
1478 /** For every transaction, indexed by TxIdx, the number of unmet dependencies the
1479 * transaction has. */
1480 std::vector<TxIdx> tx_deps(m_tx_data.size(), 0);
1481 /** A heap with all transactions within the current chunk that can be included, sorted by
1482 * tx feerate (high to low), tx size (small to large), and fallback order. */
1483 std::vector<TxIdx> ready_tx;
1484 // Populate chunk_deps and tx_deps.
1485 unsigned num_deps{0};
1486 for (TxIdx chl_idx : m_transaction_idxs) {
1487 const auto& chl_data = m_tx_data[chl_idx];
1488 tx_deps[chl_idx] = chl_data.parents.Count();
1489 num_deps += tx_deps[chl_idx];
1490 auto chl_chunk_idx = chl_data.chunk_idx;
1491 auto& chl_chunk_info = m_set_info[chl_chunk_idx];
1492 chunk_deps[chl_chunk_idx] += (chl_data.parents - chl_chunk_info.transactions).Count();
1493 }
1494 /** Function to compute the highest element of a chunk, by fallback_order. */
1495 auto max_fallback_fn = [&](SetIdx chunk_idx) noexcept {
1496 auto& chunk = m_set_info[chunk_idx].transactions;
1497 auto it = chunk.begin();
1498 DepGraphIndex ret = *it;
1499 ++it;
1500 while (it != chunk.end()) {
1501 if (fallback_order(*it, ret) > 0) ret = *it;
1502 ++it;
1503 }
1504 return ret;
1505 };
1506 /** Comparison function for the transaction heap. Note that it is a max-heap, so
1507 * tx_cmp_fn(a, b) == true means "a appears after b in the linearization". */
1508 auto tx_cmp_fn = [&](const auto& a, const auto& b) noexcept {
1509 // Bail out for identical transactions.
1510 if (a == b) return false;
1511 // First sort by increasing transaction feerate.
1512 auto& a_feerate = m_depgraph.FeeRate(a);
1513 auto& b_feerate = m_depgraph.FeeRate(b);
1514 auto feerate_cmp = ByRatio{a_feerate} <=> ByRatio{b_feerate};
1515 if (feerate_cmp != 0) return feerate_cmp < 0;
1516 // Then by decreasing transaction size.
1517 if (a_feerate.size != b_feerate.size) {
1518 return a_feerate.size > b_feerate.size;
1519 }
1520 // Tie-break by decreasing fallback_order.
1521 auto fallback_cmp = fallback_order(a, b);
1522 if (fallback_cmp != 0) return fallback_cmp > 0;

Callers 2

LinearizeFunction · 0.80
FUZZ_TARGETFunction · 0.80

Calls 13

GetLinearizationBeginMethod · 0.80
FeeRateMethod · 0.80
GetLinearizationEndMethod · 0.80
reserveMethod · 0.45
sizeMethod · 0.45
CountMethod · 0.45
beginMethod · 0.45
endMethod · 0.45
emplace_backMethod · 0.45
emptyMethod · 0.45
frontMethod · 0.45
pop_backMethod · 0.45

Tested by 1

FUZZ_TARGETFunction · 0.64