diff --git a/src/txgraph.cpp b/src/txgraph.cpp index 2ef2f7b2c3e..28a2790cc81 100644 --- a/src/txgraph.cpp +++ b/src/txgraph.cpp @@ -331,23 +331,27 @@ void Cluster::Updated(TxGraphImpl& graph) noexcept auto& entry = graph.m_entries[m_mapping[idx]]; entry.m_locator.SetPresent(this, idx); } - - // Compute its chunking and store its information in the Entry's m_chunk_feerate. - LinearizationChunking chunking(m_depgraph, m_linearization); - LinearizationIndex lin_idx{0}; - // Iterate over the chunks. - for (unsigned chunk_idx = 0; chunk_idx < chunking.NumChunksLeft(); ++chunk_idx) { - auto chunk = chunking.GetChunk(chunk_idx); - Assume(chunk.transactions.Any()); - // Iterate over the transactions in the linearization, which must match those in chunk. - do { - DepGraphIndex idx = m_linearization[lin_idx++]; - GraphIndex graph_idx = m_mapping[idx]; - auto& entry = graph.m_entries[graph_idx]; - entry.m_chunk_feerate = FeePerWeight::FromFeeFrac(chunk.feerate); - Assume(chunk.transactions[idx]); - chunk.transactions.Reset(idx); - } while(chunk.transactions.Any()); + // If the Cluster's quality is ACCEPTABLE or OPTIMAL, compute its chunking and store its + // information in the Entry's m_chunk_feerate. These fields are only accessed after making + // the entire graph ACCEPTABLE, so it is pointless to compute these if we haven't reached that + // quality level yet. + if (IsAcceptable()) { + LinearizationChunking chunking(m_depgraph, m_linearization); + LinearizationIndex lin_idx{0}; + // Iterate over the chunks. + for (unsigned chunk_idx = 0; chunk_idx < chunking.NumChunksLeft(); ++chunk_idx) { + auto chunk = chunking.GetChunk(chunk_idx); + Assume(chunk.transactions.Any()); + // Iterate over the transactions in the linearization, which must match those in chunk. + do { + DepGraphIndex idx = m_linearization[lin_idx++]; + GraphIndex graph_idx = m_mapping[idx]; + auto& entry = graph.m_entries[graph_idx]; + entry.m_chunk_feerate = FeePerWeight::FromFeeFrac(chunk.feerate); + Assume(chunk.transactions[idx]); + chunk.transactions.Reset(idx); + } while(chunk.transactions.Any()); + } } } @@ -409,8 +413,6 @@ bool Cluster::Split(TxGraphImpl& graph) noexcept // The existing Cluster is an entire component. Leave it be, but update its quality. Assume(todo == m_depgraph.Positions()); graph.SetClusterQuality(m_quality, m_setindex, QualityLevel::NEEDS_RELINEARIZE); - // We need to recompute and cache its chunking. - Updated(graph); return false; } first = false; @@ -1262,12 +1264,12 @@ void Cluster::SanityCheck(const TxGraphImpl& graph) const assert(entry.m_locator.cluster == this); assert(entry.m_locator.index == lin_pos); // Check linearization position and chunk feerate. - if (!linchunking.GetChunk(0).transactions[lin_pos]) { - linchunking.MarkDone(linchunking.GetChunk(0).transactions); - } - assert(entry.m_chunk_feerate == linchunking.GetChunk(0).feerate); - // If this Cluster has an acceptable quality level, its chunks must be connected. if (IsAcceptable()) { + if (!linchunking.GetChunk(0).transactions[lin_pos]) { + linchunking.MarkDone(linchunking.GetChunk(0).transactions); + } + assert(entry.m_chunk_feerate == linchunking.GetChunk(0).feerate); + // If this Cluster has an acceptable quality level, its chunks must be connected. assert(m_depgraph.IsConnected(linchunking.GetChunk(0).transactions)); } }