txgraph: abstract out creation of empty Clusters (refactor)
What changed, and why it matters
This is a small internal code cleanup in Bitcoin Core's transaction graph module. It introduces helper functions to create empty cluster objects and replaces three direct object-creation calls with those helpers. There is no change to network behavior, consensus rules, or user-visible functionality.
No security action required. Treat as ordinary refactoring code review.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The commit refactors src/txgraph.cpp by adding CreateEmptyGenericCluster() and CreateEmptyCluster(DepGraphIndex tx_count) methods to TxGraphImpl, then uses them in CopyToStaging, Split, and AddTransaction. The new CreateEmptyCluster currently ignores its tx_count argument and delegates to CreateEmptyGenericCluster, preserving the prior behavior exactly. This appears to be preparatory work for future cluster-implementation selection based on transaction count.
Changed components
src/txgraph.cppInspect captured patch +15 / −3
diff --git a/src/txgraph.cpp b/src/txgraph.cpp
index 6d45fb89..a09754ab 100644
--- a/src/txgraph.cpp
+++ b/src/txgraph.cpp
@@ -578,6 +578,18 @@ public:
void ClearChunkData(Entry& entry) noexcept;
/** Give an Entry a ChunkData object. */
void CreateChunkData(GraphIndex idx, LinearizationIndex chunk_count) noexcept;
+ /** Create an empty GenericClusterImpl object. */
+ std::unique_ptr<GenericClusterImpl> CreateEmptyGenericCluster() noexcept
+ {
+ return std::make_unique<GenericClusterImpl>(m_next_sequence_counter++);
+ }
+ /** Create an empty Cluster of the appropriate implementation for the specified (maximum) tx
+ * count. */
+ std::unique_ptr<Cluster> CreateEmptyCluster(DepGraphIndex tx_count) noexcept
+ {
+ (void)tx_count;
+ return CreateEmptyGenericCluster();
+ }
// Functions for handling Refs.
@@ -945,7 +957,7 @@ std::vector<Cluster*> TxGraphImpl::GetConflicts() const noexcept
Cluster* GenericClusterImpl::CopyToStaging(TxGraphImpl& graph) const noexcept
{
// Construct an empty Cluster.
- auto ret = std::make_unique<GenericClusterImpl>(graph.m_next_sequence_counter++);
+ auto ret = graph.CreateEmptyGenericCluster();
auto ptr = ret.get();
// Copy depgraph, mapping, and linearization/
ptr->m_depgraph = m_depgraph;
@@ -1136,7 +1148,7 @@ bool GenericClusterImpl::Split(TxGraphImpl& graph, int level) noexcept
}
first = false;
// Construct a new Cluster to hold the found component.
- auto new_cluster = std::make_unique<GenericClusterImpl>(graph.m_next_sequence_counter++);
+ auto new_cluster = graph.CreateEmptyCluster(component_size);
new_clusters.push_back(new_cluster.get());
// Remember that all the component's transactions go to this new Cluster. The positions
// will be determined below, so use -1 for now.
@@ -1855,7 +1867,7 @@ TxGraph::Ref TxGraphImpl::AddTransaction(const FeePerWeight& feerate) noexcept
GetRefIndex(ret) = idx;
// Construct a new singleton Cluster (which is necessarily optimally linearized).
bool oversized = uint64_t(feerate.size) > m_max_cluster_size;
- auto cluster = std::make_unique<GenericClusterImpl>(m_next_sequence_counter++);
+ auto cluster = CreateEmptyCluster(1);
cluster->AppendTransaction(idx, feerate);
auto cluster_ptr = cluster.get();
int level = GetTopLevel();
Why this scored 15/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.