@@ -141,6 +141,54 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
141
141
return std::nullopt;
142
142
}
143
143
144
+ std::vector<uint32_t > GetDustIndexes (const CTransactionRef tx_ref, CFeeRate dust_relay_rate)
145
+ {
146
+ std::vector<uint32_t > dust_indexes;
147
+ for (size_t i = 0 ; i < tx_ref->vout .size (); ++i) {
148
+ const auto & output = tx_ref->vout [i];
149
+ if (IsDust (output, dust_relay_rate)) dust_indexes.push_back (i);
150
+ }
151
+
152
+ return dust_indexes;
153
+ }
154
+
155
+ void CheckMempoolEphemeralInvariants (const CTxMemPool& tx_pool)
156
+ {
157
+ LOCK (tx_pool.cs );
158
+ for (const auto & tx_info : tx_pool.infoAll ()) {
159
+ const auto & entry = *Assert (tx_pool.GetEntry (tx_info.tx ->GetHash ()));
160
+
161
+ std::vector<uint32_t > dust_indexes = GetDustIndexes (tx_info.tx , tx_pool.m_opts .dust_relay_feerate );
162
+
163
+ Assert (dust_indexes.size () < 2 );
164
+
165
+ if (dust_indexes.empty ()) continue ;
166
+
167
+ // Transaction must have no base fee
168
+ Assert (entry.GetFee () == 0 && entry.GetModifiedFee () == 0 );
169
+
170
+ // Transaction has single dust; make sure it's swept or will not be mined
171
+ const auto & children = entry.GetMemPoolChildrenConst ();
172
+
173
+ // Multiple children should never happen as non-dust-spending child
174
+ // can get mined as package
175
+ Assert (children.size () < 2 );
176
+
177
+ if (children.empty ()) {
178
+ // No children and no fees; modified fees aside won't get mined so it's fine
179
+ // Happens naturally if child spend is RBF cycled away.
180
+ continue ;
181
+ }
182
+
183
+ // Only-child should be spending the dust
184
+ const auto & only_child = children.begin ()->get ().GetTx ();
185
+ COutPoint dust_outpoint{tx_info.tx ->GetHash (), dust_indexes[0 ]};
186
+ Assert (std::any_of (only_child.vin .begin (), only_child.vin .end (), [&dust_outpoint](const CTxIn& txin) {
187
+ return txin.prevout == dust_outpoint;
188
+ }));
189
+ }
190
+ }
191
+
144
192
void CheckMempoolTRUCInvariants (const CTxMemPool& tx_pool)
145
193
{
146
194
LOCK (tx_pool.cs );
0 commit comments