@@ -141,6 +141,54 @@ std::optional<std::string> CheckPackageMempoolAcceptResult(const Package& txns,
141141 return std::nullopt ;
142142}
143143
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+
144192void CheckMempoolTRUCInvariants (const CTxMemPool& tx_pool)
145193{
146194 LOCK (tx_pool.cs );
0 commit comments