@@ -230,6 +230,9 @@ class TxGraphImpl final : public TxGraph
230
230
/* * Total number of transactions in this graph (sum of all transaction counts in all
231
231
* Clusters, and for staging also those inherited from the main ClusterSet). */
232
232
GraphIndex m_txcount{0 };
233
+ /* * Whether this graph is oversized (if known). This roughly matches
234
+ * m_group_data->m_group_oversized, but may be known even if m_group_data is not. */
235
+ std::optional<bool > m_oversized{false };
233
236
234
237
ClusterSet () noexcept = default ;
235
238
};
@@ -1204,6 +1207,7 @@ void TxGraphImpl::GroupClusters(int level) noexcept
1204
1207
}
1205
1208
Assume (an_deps_it == an_deps.end ());
1206
1209
Assume (an_clusters_it == an_clusters.end ());
1210
+ clusterset.m_oversized = clusterset.m_group_data ->m_group_oversized ;
1207
1211
Compact ();
1208
1212
}
1209
1213
@@ -1237,6 +1241,8 @@ void TxGraphImpl::Merge(std::span<Cluster*> to_merge) noexcept
1237
1241
void TxGraphImpl::ApplyDependencies (int level) noexcept
1238
1242
{
1239
1243
auto & clusterset = GetClusterSet (level);
1244
+ // Do not bother computing groups if we already know the result will be oversized.
1245
+ if (clusterset.m_oversized == true ) return ;
1240
1246
// Compute the groups of to-be-merged Clusters (which also applies all removals, and splits).
1241
1247
GroupClusters (level);
1242
1248
Assume (clusterset.m_group_data .has_value ());
@@ -1348,6 +1354,7 @@ void TxGraphImpl::RemoveTransaction(const Ref& arg) noexcept
1348
1354
clusterset.m_to_remove .push_back (GetRefIndex (arg));
1349
1355
// Wipe m_group_data (as it will need to be recomputed).
1350
1356
clusterset.m_group_data .reset ();
1357
+ if (clusterset.m_oversized == true ) clusterset.m_oversized = std::nullopt;
1351
1358
}
1352
1359
1353
1360
void TxGraphImpl::AddDependency (const Ref& parent, const Ref& child) noexcept
@@ -1370,6 +1377,7 @@ void TxGraphImpl::AddDependency(const Ref& parent, const Ref& child) noexcept
1370
1377
clusterset.m_deps_to_add .emplace_back (GetRefIndex (parent), GetRefIndex (child));
1371
1378
// Wipe m_group_data (as it will need to be recomputed).
1372
1379
clusterset.m_group_data .reset ();
1380
+ if (clusterset.m_oversized == false ) clusterset.m_oversized = std::nullopt;
1373
1381
}
1374
1382
1375
1383
bool TxGraphImpl::Exists (const Ref& arg, bool main_only) noexcept
@@ -1539,12 +1547,17 @@ FeePerWeight TxGraphImpl::GetMainChunkFeerate(const Ref& arg) noexcept
1539
1547
bool TxGraphImpl::IsOversized (bool main_only) noexcept
1540
1548
{
1541
1549
size_t level = GetSpecifiedLevel (main_only);
1550
+ auto & clusterset = GetClusterSet (level);
1551
+ if (clusterset.m_oversized .has_value ()) {
1552
+ // Return cached value if known.
1553
+ return *clusterset.m_oversized ;
1554
+ }
1542
1555
// Find which Clusters will need to be merged together, as that is where the oversize
1543
1556
// property is assessed.
1544
1557
GroupClusters (level);
1545
- auto & clusterset = GetClusterSet (level);
1546
1558
Assume (clusterset.m_group_data .has_value ());
1547
- return clusterset.m_group_data ->m_group_oversized ;
1559
+ clusterset.m_oversized = clusterset.m_group_data ->m_group_oversized ;
1560
+ return *clusterset.m_oversized ;
1548
1561
}
1549
1562
1550
1563
void TxGraphImpl::StartStaging () noexcept
@@ -1553,8 +1566,10 @@ void TxGraphImpl::StartStaging() noexcept
1553
1566
Assume (!m_staging_clusterset.has_value ());
1554
1567
// Apply all remaining dependencies in main before creating a staging graph. Once staging
1555
1568
// exists, we cannot merge Clusters anymore (because of interference with Clusters being
1556
- // pulled into staging), so to make sure all inspectors are available (if not oversized),
1557
- // do all merging work now. This also involves applying all removals.
1569
+ // pulled into staging), so to make sure all inspectors are available (if not oversized), do
1570
+ // all merging work now. Call SplitAll() first, so that even if ApplyDependencies does not do
1571
+ // any thing due to knowing the result is oversized, splitting is still performed.
1572
+ SplitAll (0 );
1558
1573
ApplyDependencies (0 );
1559
1574
// Construct the staging ClusterSet.
1560
1575
m_staging_clusterset.emplace ();
@@ -1563,6 +1578,8 @@ void TxGraphImpl::StartStaging() noexcept
1563
1578
m_staging_clusterset->m_txcount = m_main_clusterset.m_txcount ;
1564
1579
m_staging_clusterset->m_deps_to_add = m_main_clusterset.m_deps_to_add ;
1565
1580
m_staging_clusterset->m_group_data = m_main_clusterset.m_group_data ;
1581
+ m_staging_clusterset->m_oversized = m_main_clusterset.m_oversized ;
1582
+ Assume (m_staging_clusterset->m_oversized .has_value ());
1566
1583
}
1567
1584
1568
1585
void TxGraphImpl::AbortStaging () noexcept
@@ -1612,6 +1629,7 @@ void TxGraphImpl::CommitStaging() noexcept
1612
1629
m_main_clusterset.m_deps_to_add = std::move (m_staging_clusterset->m_deps_to_add );
1613
1630
m_main_clusterset.m_to_remove = std::move (m_staging_clusterset->m_to_remove );
1614
1631
m_main_clusterset.m_group_data = std::move (m_staging_clusterset->m_group_data );
1632
+ m_main_clusterset.m_oversized = std::move (m_staging_clusterset->m_oversized );
1615
1633
m_main_clusterset.m_txcount = std::move (m_staging_clusterset->m_txcount );
1616
1634
// Delete the old staging graph, after all its information was moved to main.
1617
1635
m_staging_clusterset.reset ();
@@ -1789,6 +1807,11 @@ void TxGraphImpl::SanityCheck() const
1789
1807
if (!clusterset.m_deps_to_add .empty ()) compact_possible = false ;
1790
1808
if (!clusterset.m_to_remove .empty ()) compact_possible = false ;
1791
1809
if (!clusterset.m_removed .empty ()) compact_possible = false ;
1810
+
1811
+ // If m_group_data exists, its m_group_oversized must match m_oversized.
1812
+ if (clusterset.m_group_data .has_value ()) {
1813
+ assert (clusterset.m_oversized == clusterset.m_group_data ->m_group_oversized );
1814
+ }
1792
1815
}
1793
1816
1794
1817
// Verify that the contents of m_unlinked matches what was expected based on the Entry vector.
0 commit comments