Skip to content

Commit c28a602

Browse files
committed
txgraph: Introduce TxGraphImpl observer tracking (preparation)
This is preparation for a next commit which will introduce a class whose objects hold references to internals in TxGraphImpl, which disallows modifications to the graph while such objects exist.
1 parent 9095d8a commit c28a602

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

src/txgraph.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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

15121518
TxGraph::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
22472258
void 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

Comments
 (0)