-
Notifications
You must be signed in to change notification settings - Fork 60
Description
Describe the bug
We use BDK as our onchain wallet for the Bark project, an important part of that is using BDK to spend P2A outputs when users perform an emergency exit. Each "exit transaction" contains a P2A output, typically with a value of zero sats, but sometimes with a non-zero value due to how we manage fees for certain operations. When the P2A value is zero there's no problem, however when it's non-zero you can run into edge cases which result in unexpected errors.
Here's an example scenario:
- The wallet has 1 UTXO of 1,000,000 sats
- We try to create a new transaction to spend the P2A output of an exit transaction which isn't contained in the wallet itself
- We add a
drain_toaddress which is the BDK wallet - We set
absolute_feeto 200 sats (enough to broadcast the exit transaction and the transaction we're constructing as a TRUC package) - If the P2A output has a value of 0:
- BDK will pull in the 1,000,000 sat UTXO and drain to a wallet address with a 999,800 sat output
- This is as expected
- If the P2A output has a value of 1,000:
- BDK won't use any extra UTXOs and will drain to a wallet address with a 800 sat output
- This is as expected
- If the P2A output has a value of 500:
- BDK won't use any extra UTXOs and will error because it can't create a 300 sat output as that is below the dust limit
- This is not as expected
- If the P2A output has a value of 200:
- BDK won't use any extra UTXOs and will error because the remaining value is 0 and it enforces the use of at least 1 TxOut even when draining
- This is not as expected
Expected behavior
The documentation for fee_absolute states the following:
Note that this is really a minimum absolute fee -- it's possible to overshoot it slightly since adding a change output to drain the remaining excess might not be viable.
Under that assumption I would expect that when spending a P2A output which results in zero or dust change, the entire P2A value should be consumed and no output should be created. If BDK mandates there always being at least 1 TxOut, then I would expect the transaction builder to pull in the extra UTXO to drain to a non-dust output.
Build environment
- BDK tag/commit: 2.3.0
- OS+version: macOS 26.2
- Rust/Cargo version: 1.90
- Rust/Cargo target: aarch64-apple-darwin
Which backend(s) are relevant (if any)?
- Esplora
- Bitcoin Core RPC
Is this blocking production use?
- No: We work around it by trying to detect this problem and increase the fee amount to force 1 sat to be used from another UTXO
Project or organization (optional)
Bark
Additional context
This is the source code for where we encounter this issue.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status