clusterlin: fix type to count dependencies
What changed, and why it matters
This commit fixes a variable type mismatch in Bitcoin Core's transaction clustering code. The code counts dependencies between groups of transactions, but was using a transaction-index type for the count. If that count type is smaller than the actual number of dependencies, it could overflow or behave incorrectly when many dependencies exist. The fix changes the count and random-picker variables to a plain unsigned integer, which is the appropriate type for counting.
Treat as a low-risk correctness fix. Review whether TxIdx range could realistically be exceeded by dependency counts in production mempools, and consider backporting if cluster linearization is active in released versions. No immediate emergency response indicated.
Security signals we found
Integer type mismatch in counting logic
Potential overflow/truncation of dependency count
Incorrect random range selection if count wraps
Memory-pool transaction ordering correctness
Evidence from the diff
In src/cluster_linearize.h, the dependency-counting loop used TxIdx (a transaction index type) for num_deps and pick. These variables hold a count of dependency edges, not a transaction index, so using TxIdx was semantically wrong and could truncate or wrap if the dependency count exceeds the range of TxIdx. The patch changes both to unsigned, which is the correct width for counts returned by Count() and randrange(). This is a type-correctness bug fix in the cluster linearization logic used during mempool transaction ordering.
Changed components
src/cluster_linearize.hmempool cluster linearizationtransaction dependency countingInspect captured patch +2 / −2
diff --git a/src/cluster_linearize.h b/src/cluster_linearize.h
index 00627d6f..9a2166bc 100644
--- a/src/cluster_linearize.h
+++ b/src/cluster_linearize.h
@@ -845,14 +845,14 @@ private:
auto& bottom_chunk = m_tx_data[bottom_rep];
Assume(bottom_chunk.chunk_rep == bottom_rep);
// Count the number of dependencies between bottom_chunk and top_chunk.
- TxIdx num_deps{0};
+ unsigned num_deps{0};
for (auto tx : top_chunk.chunk_setinfo.transactions) {
auto& tx_data = m_tx_data[tx];
num_deps += (tx_data.children & bottom_chunk.chunk_setinfo.transactions).Count();
}
if (num_deps == 0) return TxIdx(-1);
// Uniformly randomly pick one of them and activate it.
- TxIdx pick = m_rng.randrange(num_deps);
+ unsigned pick = m_rng.randrange(num_deps);
for (auto tx : top_chunk.chunk_setinfo.transactions) {
auto& tx_data = m_tx_data[tx];
auto intersect = tx_data.children & bottom_chunk.chunk_setinfo.transactions;
Why this scored 20/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.