Skip to content

Commit e8da007

Browse files
committed
fix(chain): Unconfirmed coinbase txs should never be canonical
The logic in `CanonicalIter` will consider txs that are anchored to blocks not in the best chain since they still can appear in the mempool. However, coinbase txs can never be unconfirmed - which the old logic failed to exclude.
1 parent a7c1bcc commit e8da007

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

crates/chain/src/canonical_iter.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,10 @@ impl<A: Anchor, C: ChainOracle> Iterator for CanonicalIter<'_, A, C> {
230230
}
231231

232232
if let Some((txid, tx, last_seen)) = self.unprocessed_seen_txs.next() {
233+
debug_assert!(
234+
!tx.is_coinbase(),
235+
"Coinbase txs must not have `last_seen` (in mempool) value"
236+
);
233237
if !self.is_canonicalized(txid) {
234238
let observed_in = ObservedIn::Mempool(last_seen);
235239
self.mark_canonical(txid, tx, CanonicalReason::from_observed_in(observed_in));
@@ -238,7 +242,7 @@ impl<A: Anchor, C: ChainOracle> Iterator for CanonicalIter<'_, A, C> {
238242
}
239243

240244
if let Some((txid, tx, height)) = self.unprocessed_leftover_txs.pop_front() {
241-
if !self.is_canonicalized(txid) {
245+
if !self.is_canonicalized(txid) && !tx.is_coinbase() {
242246
let observed_in = ObservedIn::Block(height);
243247
self.mark_canonical(txid, tx, CanonicalReason::from_observed_in(observed_in));
244248
}

0 commit comments

Comments
 (0)