From: Elias Rohrer Date: Wed, 8 Apr 2026 09:43:08 +0000 (+0200) Subject: fix(chain): add missing `continue` in `CanonicalIter` assumed-tx processing X-Git-Tag: electrum-0.24.0~3^2 X-Git-Url: http://internal-gitweb-vhost/blockdata/script/encode/example_cli/struct.EncoderStringWriter.html?a=commitdiff_plain;h=27ab7ee0f212d9853fcff693f3bc22f9c6956105;p=bdk fix(chain): add missing `continue` in `CanonicalIter` assumed-tx processing Without the `continue`, the loop falls through to the subsequent processing blocks when assumed-canonical transactions are the only remaining unprocessed source. If the anchored, seen, and leftover iterators are all exhausted, the loop reaches `return None` and silently drops the assumed transactions that were just marked canonical. Co-Authored-By: HAL 9000 --- diff --git a/crates/chain/src/canonical_iter.rs b/crates/chain/src/canonical_iter.rs index 7ff04249..41f17e52 100644 --- a/crates/chain/src/canonical_iter.rs +++ b/crates/chain/src/canonical_iter.rs @@ -218,6 +218,7 @@ impl Iterator for CanonicalIter<'_, A, C> { if !self.is_canonicalized(txid) { self.mark_canonical(txid, tx, CanonicalReason::assumed()); } + continue; } if let Some((txid, tx, anchors)) = self.unprocessed_anchored_txs.next() { diff --git a/crates/chain/tests/test_tx_graph_conflicts.rs b/crates/chain/tests/test_tx_graph_conflicts.rs index 113a985b..abfd950c 100644 --- a/crates/chain/tests/test_tx_graph_conflicts.rs +++ b/crates/chain/tests/test_tx_graph_conflicts.rs @@ -943,6 +943,34 @@ fn test_tx_conflict_handling() { confirmed: Amount::ZERO, }, }, + Scenario { + name: "only assumed-canonical txs are yielded without anchored or seen txs", + tx_templates: &[ + TxTemplate { + tx_name: "assumed_a", + inputs: &[TxInTemplate::Bogus], + outputs: &[TxOutTemplate::new(21_000, Some(0))], + assume_canonical: true, + ..Default::default() + }, + TxTemplate { + tx_name: "assumed_b", + inputs: &[TxInTemplate::Bogus], + outputs: &[TxOutTemplate::new(18_000, Some(1))], + assume_canonical: true, + ..Default::default() + }, + ], + exp_chain_txs: HashSet::from(["assumed_a", "assumed_b"]), + exp_chain_txouts: HashSet::from([("assumed_a", 0), ("assumed_b", 0)]), + exp_unspents: HashSet::from([("assumed_a", 0), ("assumed_b", 0)]), + exp_balance: Balance { + immature: Amount::ZERO, + trusted_pending: Amount::from_sat(21_000 + 18_000), + untrusted_pending: Amount::ZERO, + confirmed: Amount::ZERO, + }, + }, Scenario { name: "coinbase tx must not become unconfirmed", tx_templates: &[