From 0a3351947e736c646a6dfffef24b83d003c569e7 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Sat, 10 Jan 2026 23:28:00 -0500 Subject: [PATCH] txgraph: use fallback order when linearizing (feature) Add glue to make TxGraph use the fallback order provided to it, in the fallback comparator it provides to the cluster linearization code. The order of chunks within a cluster becomes: 1. Topology (chunks after their dependencies) 2. Feerate (high to low) 3. Weight (small to large) 4. Max-txid (chunk with lowest maximum-txid first) The order of transactions within a chunk becomes: 1. Topology (parents before children) 2. Individual transaction feerate (high to low) 3. Weight (small to large) 4. Txid (low to high txid) This makes optimal cluster linearization, both the order of chunks within a chunk, and the order of transactions within those chunks, completely deterministic. --- src/txgraph.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/txgraph.cpp b/src/txgraph.cpp index 2c024c969a7..176ef613c71 100644 --- a/src/txgraph.cpp +++ b/src/txgraph.cpp @@ -2140,11 +2140,14 @@ std::pair GenericClusterImpl::Relinearize(TxGraphImpl& graph, in if (IsOptimal()) return {0, false}; // Invoke the actual linearization algorithm (passing in the existing one). uint64_t rng_seed = graph.m_rng.rand64(); - auto [linearization, optimal, cost] = Linearize(m_depgraph, max_iters, rng_seed, IndexTxOrder{}, m_linearization, /*is_topological=*/IsTopological()); - // Postlinearize to improve the linearization (if optimal, only the sub-chunk order), and - // reduce the amount of information the IndexTxOrder-based fallback order leaks about - // DepGraphIndexes in the cluster. This also guarantees that all chunks are connected (even - // when non-optimal). + const auto fallback_order = [&](DepGraphIndex a, DepGraphIndex b) noexcept { + const auto ref_a = graph.m_entries[m_mapping[a]].m_ref; + const auto ref_b = graph.m_entries[m_mapping[b]].m_ref; + return graph.m_fallback_order(*ref_a, *ref_b); + }; + auto [linearization, optimal, cost] = Linearize(m_depgraph, max_iters, rng_seed, fallback_order, m_linearization, /*is_topological=*/IsTopological()); + // Postlinearize to improve the linearization (if optimal, only the sub-chunk order). + // This also guarantees that all chunks are connected (even when non-optimal). PostLinearize(m_depgraph, linearization); // Update the linearization. m_linearization = std::move(linearization);