@@ -318,6 +318,8 @@ class TxGraphImpl final : public TxGraph
318318 /* * Index of ChunkData objects, indexing the last transaction in each chunk in the main
319319 * graph. */
320320 ChunkIndex m_main_chunkindex;
321+ /* * Number of index-observing objects in existence. */
322+ size_t m_main_chunkindex_observers{0 };
321323
322324 /* * A Locator that describes whether, where, and in which Cluster an Entry appears.
323325 * Every Entry has MAX_LEVELS locators, as it may appear in one Cluster per level.
@@ -453,6 +455,7 @@ class TxGraphImpl final : public TxGraph
453455 {
454456 auto & entry = m_entries[idx];
455457 Assume (entry.m_ref != nullptr );
458+ Assume (m_main_chunkindex_observers == 0 || !entry.m_locator [0 ].IsPresent ());
456459 entry.m_ref = nullptr ;
457460 // Mark the transaction as to be removed in all levels where it explicitly or implicitly
458461 // exists.
@@ -581,6 +584,7 @@ void TxGraphImpl::ClearLocator(int level, GraphIndex idx) noexcept
581584 }
582585 }
583586 if (level == 0 && entry.m_main_chunkindex_iterator != m_main_chunkindex.end ()) {
587+ Assume (m_main_chunkindex_observers == 0 );
584588 m_main_chunkindex.erase (entry.m_main_chunkindex_iterator );
585589 entry.m_main_chunkindex_iterator = m_main_chunkindex.end ();
586590 }
@@ -594,6 +598,7 @@ void Cluster::Updated(TxGraphImpl& graph) noexcept
594598 if (m_level == 0 && entry.m_main_chunkindex_iterator != graph.m_main_chunkindex .end ()) {
595599 // Destroy any potential ChunkData prior to modifying the Cluster (as that could
596600 // invalidate its ordering).
601+ Assume (graph.m_main_chunkindex_observers == 0 );
597602 graph.m_main_chunkindex .erase (entry.m_main_chunkindex_iterator );
598603 entry.m_main_chunkindex_iterator = graph.m_main_chunkindex .end ();
599604 }
@@ -887,6 +892,7 @@ void Cluster::Merge(TxGraphImpl& graph, Cluster& other) noexcept
887892 if (m_level == 0 && entry.m_main_chunkindex_iterator != graph.m_main_chunkindex .end ()) {
888893 // Destroy any potential ChunkData prior to modifying the Cluster (as that could
889894 // invalidate its ordering).
895+ Assume (graph.m_main_chunkindex_observers == 0 );
890896 graph.m_main_chunkindex .erase (entry.m_main_chunkindex_iterator );
891897 entry.m_main_chunkindex_iterator = graph.m_main_chunkindex .end ();
892898 }
@@ -1511,6 +1517,7 @@ Cluster::Cluster(uint64_t sequence, TxGraphImpl& graph, const FeePerWeight& feer
15111517
15121518TxGraph::Ref TxGraphImpl::AddTransaction (const FeePerWeight& feerate) noexcept
15131519{
1520+ Assume (m_main_chunkindex_observers == 0 || GetTopLevel () != 0 );
15141521 // Construct a new Ref.
15151522 Ref ret;
15161523 // Construct a new Entry, and link it with the Ref.
@@ -1539,6 +1546,7 @@ void TxGraphImpl::RemoveTransaction(const Ref& arg) noexcept
15391546 // having been removed).
15401547 if (GetRefGraph (arg) == nullptr ) return ;
15411548 Assume (GetRefGraph (arg) == this );
1549+ Assume (m_main_chunkindex_observers == 0 || GetTopLevel () != 0 );
15421550 // Find the Cluster the transaction is in, and stop if it isn't in any.
15431551 int level = GetTopLevel ();
15441552 auto cluster = FindCluster (GetRefIndex (arg), level);
@@ -1557,6 +1565,7 @@ void TxGraphImpl::AddDependency(const Ref& parent, const Ref& child) noexcept
15571565 // removed).
15581566 if (GetRefGraph (parent) == nullptr || GetRefGraph (child) == nullptr ) return ;
15591567 Assume (GetRefGraph (parent) == this && GetRefGraph (child) == this );
1568+ Assume (m_main_chunkindex_observers == 0 || GetTopLevel () != 0 );
15601569 // Don't do anything if this is a dependency on self.
15611570 if (GetRefIndex (parent) == GetRefIndex (child)) return ;
15621571 // Find the Cluster the parent and child transaction are in, and stop if either appears to be
@@ -1895,6 +1904,7 @@ void TxGraphImpl::CommitStaging() noexcept
18951904{
18961905 // Staging must exist.
18971906 Assume (m_staging_clusterset.has_value ());
1907+ Assume (m_main_chunkindex_observers == 0 );
18981908 // Delete all conflicting Clusters in main, to make place for moving the staging ones
18991909 // there. All of these have been copied to staging in PullIn().
19001910 auto conflicts = GetConflicts ();
@@ -1947,6 +1957,7 @@ void TxGraphImpl::SetTransactionFee(const Ref& ref, int64_t fee) noexcept
19471957 // Don't do anything if the passed Ref is empty.
19481958 if (GetRefGraph (ref) == nullptr ) return ;
19491959 Assume (GetRefGraph (ref) == this );
1960+ Assume (m_main_chunkindex_observers == 0 );
19501961 // Find the entry, its locator, and inform its Cluster about the new feerate, if any.
19511962 auto & entry = m_entries[GetRefIndex (ref)];
19521963 for (int level = 0 ; level < MAX_LEVELS; ++level) {
@@ -2247,7 +2258,9 @@ void TxGraphImpl::SanityCheck() const
22472258void TxGraphImpl::DoWork () noexcept
22482259{
22492260 for (int level = 0 ; level <= GetTopLevel (); ++level) {
2250- MakeAllAcceptable (level);
2261+ if (level > 0 || m_main_chunkindex_observers == 0 ) {
2262+ MakeAllAcceptable (level);
2263+ }
22512264 }
22522265}
22532266
0 commit comments