Skip to content

Reachable panic in Utxo::txout #474

@ValuedMammal

Description

@ValuedMammal

Utxo::txout() returns &TxOut but contains two reachable panics for the Foreign variant:

  1. prev_tx.output[outpoint.vout as usize] — panics if the attached non_witness_utxo has fewer outputs than the outpoint.vout indicates.
  2. unreachable!("Foreign UTXOs will always have one of these set") — asserts an invariant the type does not enforce. Because Utxo::Foreign is a public enum variant with public fields, a caller can theoretically construct one with an empty psbt::Input, making this branch reachable.

The validation that guards against these states lives in TxBuilder::add_foreign_utxo_with_sequence but is bypassed by any direct construction of Utxo::Foreign.

To Reproduce

let utxo = Utxo::Foreign {
    outpoint: OutPoint::null(),
    sequence: Sequence::MAX,
    psbt_input: Box::new(psbt::Input::default()),
};
utxo.txout();

Expected behavior

txout() should not panic on a value that is constructable through the public API.

Build environment

  • BDK tag/commit: current master
  • OS+version:
  • Rust/Cargo version:
  • Rust/Cargo target:

Which backend(s) are relevant (if any)?

  • None / not backend-related

Is this blocking production use?

  • Yes
  • No

Additional context

Raised during review of #445. Three options identified:

  1. Make Utxo::Foreign wrap a type with private fields.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    Status

    Discussion

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions