-
Notifications
You must be signed in to change notification settings - Fork 418
Description
Describe the bug
I tried to pass a Txid to CanonicalizationParams::assume_canonical, which I expected to be confirmed by a direct anchor, but in the set of canonical txs that is returned the chain position of the assumed tx appeared as ChainPosition::Unconfirmed. This later caused unexpected results at the time of doing coin selection.
Currently when a txid is assumed to be canonical, returning a chain position of ChainPosition::Confirmed is only possible if the CanonicalReason's descendant has some value.
bdk/crates/chain/src/canonical_task.rs
Lines 216 to 221 in 88a99ba
| CanonicalReason::Assumed { descendant } => match descendant { | |
| Some(_) => match self.direct_anchors.get(txid) { | |
| Some(confirmed_anchor) => ChainPosition::Confirmed { | |
| anchor: confirmed_anchor, | |
| transitively: None, | |
| }, |
Expected behavior
CanonicalReason::Assumed should map to ChainPosition::Confirmed if a direct anchor exists.
- If the reason carries a
descendanttxid that is confirmed by a direct anchor, I would expect a chain position that is transitively confirmed by the descendant. - If the assumed tx is confirmed by a direct anchor and is not accompanied by a
descendant, I would expect a chain position that is confirmed by the direct anchor and atransitivelyofNone. - If neither the assumed tx nor a descendant are confirmed by a direct anchor, I would expect
ChainPosition::Unconfirmed.
To Reproduce
I added this test case to demonstrate what I think is the expected behavior. Notice B is both assumed and confirmed.
test_tx_graph_conflicts.rs
Scenario {
name: "B and C are confirmed, C1 spends C, all are assume-canonical",
tx_templates: &[
TxTemplate {
tx_name: "B",
inputs: &[TxInTemplate::Bogus],
outputs: &[TxOutTemplate::new(10_000, Some(0))],
anchors: &[block_id!(1, "B")],
last_seen: None,
assume_canonical: true,
},
TxTemplate {
tx_name: "C",
inputs: &[TxInTemplate::Bogus],
outputs: &[TxOutTemplate::new(8_000, Some(0))],
anchors: &[block_id!(2, "C")],
last_seen: None,
assume_canonical: true,
},
TxTemplate {
tx_name: "C1",
inputs: &[TxInTemplate::PrevTx("C", 0)],
outputs: &[TxOutTemplate::new(6_000, Some(0))],
assume_canonical: true,
..Default::default()
}
],
exp_chain_txs: HashSet::from(["B", "C", "C1"]),
exp_chain_txouts: HashSet::from([("B", 0), ("C", 0), ("C1", 0)]),
exp_unspents: HashSet::from([("B", 0), ("C1", 0)]),
exp_balance: Balance {
immature: Amount::ZERO,
trusted_pending: Amount::from_sat(6_000),
untrusted_pending: Amount::ZERO,
confirmed: Amount::from_sat(10_000),
}
}Build environment
- BDK tag/commit: 88a99ba
- Rust/Cargo version: 1.88.0
Is this blocking production use?
- Yes
- No
Metadata
Metadata
Assignees
Labels
Type
Projects
Status