@@ -318,6 +318,8 @@ class TxGraphImpl final : public TxGraph
318
318
/* * Index of ChunkData objects, indexing the last transaction in each chunk in the main
319
319
* graph. */
320
320
ChunkIndex m_main_chunkindex;
321
+ /* * Number of index-observing objects in existence. */
322
+ size_t m_main_chunkindex_observers{0 };
321
323
322
324
/* * A Locator that describes whether, where, and in which Cluster an Entry appears.
323
325
* Every Entry has MAX_LEVELS locators, as it may appear in one Cluster per level.
@@ -453,6 +455,7 @@ class TxGraphImpl final : public TxGraph
453
455
{
454
456
auto & entry = m_entries[idx];
455
457
Assume (entry.m_ref != nullptr );
458
+ Assume (m_main_chunkindex_observers == 0 || !entry.m_locator [0 ].IsPresent ());
456
459
entry.m_ref = nullptr ;
457
460
// Mark the transaction as to be removed in all levels where it explicitly or implicitly
458
461
// exists.
@@ -581,6 +584,7 @@ void TxGraphImpl::ClearLocator(int level, GraphIndex idx) noexcept
581
584
}
582
585
}
583
586
if (level == 0 && entry.m_main_chunkindex_iterator != m_main_chunkindex.end ()) {
587
+ Assume (m_main_chunkindex_observers == 0 );
584
588
m_main_chunkindex.erase (entry.m_main_chunkindex_iterator );
585
589
entry.m_main_chunkindex_iterator = m_main_chunkindex.end ();
586
590
}
@@ -594,6 +598,7 @@ void Cluster::Updated(TxGraphImpl& graph) noexcept
594
598
if (m_level == 0 && entry.m_main_chunkindex_iterator != graph.m_main_chunkindex .end ()) {
595
599
// Destroy any potential ChunkData prior to modifying the Cluster (as that could
596
600
// invalidate its ordering).
601
+ Assume (graph.m_main_chunkindex_observers == 0 );
597
602
graph.m_main_chunkindex .erase (entry.m_main_chunkindex_iterator );
598
603
entry.m_main_chunkindex_iterator = graph.m_main_chunkindex .end ();
599
604
}
@@ -887,6 +892,7 @@ void Cluster::Merge(TxGraphImpl& graph, Cluster& other) noexcept
887
892
if (m_level == 0 && entry.m_main_chunkindex_iterator != graph.m_main_chunkindex .end ()) {
888
893
// Destroy any potential ChunkData prior to modifying the Cluster (as that could
889
894
// invalidate its ordering).
895
+ Assume (graph.m_main_chunkindex_observers == 0 );
890
896
graph.m_main_chunkindex .erase (entry.m_main_chunkindex_iterator );
891
897
entry.m_main_chunkindex_iterator = graph.m_main_chunkindex .end ();
892
898
}
@@ -1511,6 +1517,7 @@ Cluster::Cluster(uint64_t sequence, TxGraphImpl& graph, const FeePerWeight& feer
1511
1517
1512
1518
TxGraph::Ref TxGraphImpl::AddTransaction (const FeePerWeight& feerate) noexcept
1513
1519
{
1520
+ Assume (m_main_chunkindex_observers == 0 || GetTopLevel () != 0 );
1514
1521
// Construct a new Ref.
1515
1522
Ref ret;
1516
1523
// Construct a new Entry, and link it with the Ref.
@@ -1539,6 +1546,7 @@ void TxGraphImpl::RemoveTransaction(const Ref& arg) noexcept
1539
1546
// having been removed).
1540
1547
if (GetRefGraph (arg) == nullptr ) return ;
1541
1548
Assume (GetRefGraph (arg) == this );
1549
+ Assume (m_main_chunkindex_observers == 0 || GetTopLevel () != 0 );
1542
1550
// Find the Cluster the transaction is in, and stop if it isn't in any.
1543
1551
int level = GetTopLevel ();
1544
1552
auto cluster = FindCluster (GetRefIndex (arg), level);
@@ -1557,6 +1565,7 @@ void TxGraphImpl::AddDependency(const Ref& parent, const Ref& child) noexcept
1557
1565
// removed).
1558
1566
if (GetRefGraph (parent) == nullptr || GetRefGraph (child) == nullptr ) return ;
1559
1567
Assume (GetRefGraph (parent) == this && GetRefGraph (child) == this );
1568
+ Assume (m_main_chunkindex_observers == 0 || GetTopLevel () != 0 );
1560
1569
// Don't do anything if this is a dependency on self.
1561
1570
if (GetRefIndex (parent) == GetRefIndex (child)) return ;
1562
1571
// 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
1895
1904
{
1896
1905
// Staging must exist.
1897
1906
Assume (m_staging_clusterset.has_value ());
1907
+ Assume (m_main_chunkindex_observers == 0 );
1898
1908
// Delete all conflicting Clusters in main, to make place for moving the staging ones
1899
1909
// there. All of these have been copied to staging in PullIn().
1900
1910
auto conflicts = GetConflicts ();
@@ -1947,6 +1957,7 @@ void TxGraphImpl::SetTransactionFee(const Ref& ref, int64_t fee) noexcept
1947
1957
// Don't do anything if the passed Ref is empty.
1948
1958
if (GetRefGraph (ref) == nullptr ) return ;
1949
1959
Assume (GetRefGraph (ref) == this );
1960
+ Assume (m_main_chunkindex_observers == 0 );
1950
1961
// Find the entry, its locator, and inform its Cluster about the new feerate, if any.
1951
1962
auto & entry = m_entries[GetRefIndex (ref)];
1952
1963
for (int level = 0 ; level < MAX_LEVELS; ++level) {
@@ -2247,7 +2258,9 @@ void TxGraphImpl::SanityCheck() const
2247
2258
void TxGraphImpl::DoWork () noexcept
2248
2259
{
2249
2260
for (int level = 0 ; level <= GetTopLevel (); ++level) {
2250
- MakeAllAcceptable (level);
2261
+ if (level > 0 || m_main_chunkindex_observers == 0 ) {
2262
+ MakeAllAcceptable (level);
2263
+ }
2251
2264
}
2252
2265
}
2253
2266
0 commit comments