From df9eb72b129b999eb5e327c51fd580ba9910a778 Mon Sep 17 00:00:00 2001 From: Greg Sanders Date: Wed, 10 Jun 2026 12:17:02 -0400 Subject: [PATCH] test: ensure group data cluster pointers are live --- src/txgraph.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/txgraph.cpp b/src/txgraph.cpp index 39a8a8814ab..4138e835f8a 100644 --- a/src/txgraph.cpp +++ b/src/txgraph.cpp @@ -2939,6 +2939,8 @@ void TxGraphImpl::SanityCheck() const std::set expected_removed[MAX_LEVELS]; /** Which Cluster::m_sequence values have been encountered. */ std::set sequences; + /** Which Clusters are live in ClusterSet::m_clusters up to the level being checked. */ + std::set live_clusters; /** Which GraphIndexes ought to occur in m_main_chunkindex, based on m_entries. */ std::set expected_chunkindex; /** Whether compaction is possible in the current state. */ @@ -3000,6 +3002,7 @@ void TxGraphImpl::SanityCheck() const // ... for all clusters in them ... for (ClusterSetIndex setindex = 0; setindex < quality_clusters.size(); ++setindex) { const auto& cluster = *quality_clusters[setindex]; + live_clusters.insert(&cluster); // The number of transactions in a Cluster cannot exceed m_max_cluster_count. assert(cluster.GetTxCount() <= m_max_cluster_count); // The level must match the Cluster's own idea of what level it is in (but GetLevel @@ -3062,6 +3065,16 @@ void TxGraphImpl::SanityCheck() const // Verify that the actually encountered clusters match the ones occurring in Entry vector. assert(actual_clusters == expected_clusters[level]); + // Validate m_group_data cluster pointers refer to live clusters at this + // level or below (staging group data may reference not-yet-pulled-in + // main clusters). + if (clusterset.m_group_data.has_value()) { + for (const Cluster* cl : clusterset.m_group_data->m_group_clusters) { + assert(live_clusters.contains(cl)); + assert(cl->GetTxCount() > 0); + assert(FindCluster(cl->GetClusterEntry(0), level) == cl); + } + } // Verify that the contents of m_removed matches what was expected based on the Entry vector. std::set actual_removed(clusterset.m_removed.begin(), clusterset.m_removed.end()); for (auto i : expected_unlinked) {