@@ -221,6 +221,8 @@ class TxGraphImpl final : public TxGraph
221
221
Ref* m_ref{nullptr };
222
222
/* * Which Cluster and position therein this Entry appears in. */
223
223
Locator m_locator;
224
+ /* * The chunk feerate of this transaction (if not missing). */
225
+ FeePerWeight m_chunk_feerate;
224
226
};
225
227
226
228
/* * The set of all transactions. GraphIndex values index into this. */
@@ -301,6 +303,7 @@ class TxGraphImpl final : public TxGraph
301
303
void SetTransactionFee (const Ref&, int64_t fee) noexcept final ;
302
304
303
305
bool Exists (const Ref& arg) noexcept final ;
306
+ FeePerWeight GetChunkFeerate (const Ref& arg) noexcept final ;
304
307
FeePerWeight GetIndividualFeerate (const Ref& arg) noexcept final ;
305
308
std::vector<Ref*> GetCluster (const Ref& arg) noexcept final ;
306
309
std::vector<Ref*> GetAncestors (const Ref& arg) noexcept final ;
@@ -317,6 +320,24 @@ void Cluster::Updated(TxGraphImpl& graph) noexcept
317
320
auto & entry = graph.m_entries [m_mapping[idx]];
318
321
entry.m_locator .SetPresent (this , idx);
319
322
}
323
+
324
+ // Compute its chunking and store its information in the Entry's m_chunk_feerate.
325
+ LinearizationChunking chunking (m_depgraph, m_linearization);
326
+ LinearizationIndex lin_idx{0 };
327
+ // Iterate over the chunks.
328
+ for (unsigned chunk_idx = 0 ; chunk_idx < chunking.NumChunksLeft (); ++chunk_idx) {
329
+ auto chunk = chunking.GetChunk (chunk_idx);
330
+ Assume (chunk.transactions .Any ());
331
+ // Iterate over the transactions in the linearization, which must match those in chunk.
332
+ do {
333
+ DepGraphIndex idx = m_linearization[lin_idx++];
334
+ GraphIndex graph_idx = m_mapping[idx];
335
+ auto & entry = graph.m_entries [graph_idx];
336
+ entry.m_chunk_feerate = FeePerWeight::FromFeeFrac (chunk.feerate );
337
+ Assume (chunk.transactions [idx]);
338
+ chunk.transactions .Reset (idx);
339
+ } while (chunk.transactions .Any ());
340
+ }
320
341
}
321
342
322
343
void Cluster::ApplyRemovals (TxGraphImpl& graph, std::span<GraphIndex>& to_remove) noexcept
@@ -1108,6 +1129,23 @@ FeePerWeight TxGraphImpl::GetIndividualFeerate(const Ref& arg) noexcept
1108
1129
return cluster->GetIndividualFeerate (m_entries[GetRefIndex (arg)].m_locator .index );
1109
1130
}
1110
1131
1132
+ FeePerWeight TxGraphImpl::GetChunkFeerate (const Ref& arg) noexcept
1133
+ {
1134
+ // Return the empty FeePerWeight if the passed Ref is empty.
1135
+ if (GetRefGraph (arg) == nullptr ) return {};
1136
+ Assume (GetRefGraph (arg) == this );
1137
+ // Apply all removals and dependencies, as the result might be inaccurate otherwise.
1138
+ ApplyDependencies ();
1139
+ // Find the cluster the argument is in, and return the empty FeePerWeight if it isn't in any.
1140
+ auto cluster = m_entries[GetRefIndex (arg)].m_locator .cluster ;
1141
+ if (cluster == nullptr ) return {};
1142
+ // Make sure the Cluster has an acceptable quality level, and then return the transaction's
1143
+ // chunk feerate.
1144
+ MakeAcceptable (*cluster);
1145
+ const auto & entry = m_entries[GetRefIndex (arg)];
1146
+ return entry.m_chunk_feerate ;
1147
+ }
1148
+
1111
1149
void Cluster::SetFee (TxGraphImpl& graph, DepGraphIndex idx, int64_t fee) noexcept
1112
1150
{
1113
1151
// Make sure the specified DepGraphIndex exists in this Cluster.
@@ -1159,10 +1197,11 @@ void Cluster::SanityCheck(const TxGraphImpl& graph) const
1159
1197
// Check that the Entry has a locator pointing back to this Cluster & position within it.
1160
1198
assert (entry.m_locator .cluster == this );
1161
1199
assert (entry.m_locator .index == lin_pos);
1162
- // Check linearization position.
1200
+ // Check linearization position and chunk feerate .
1163
1201
if (!linchunking.GetChunk (0 ).transactions [lin_pos]) {
1164
1202
linchunking.MarkDone (linchunking.GetChunk (0 ).transactions );
1165
1203
}
1204
+ assert (entry.m_chunk_feerate == linchunking.GetChunk (0 ).feerate );
1166
1205
// If this Cluster has an acceptable quality level, its chunks must be connected.
1167
1206
if (IsAcceptable ()) {
1168
1207
assert (m_depgraph.IsConnected (linchunking.GetChunk (0 ).transactions ));
0 commit comments