feat: Add Wallet::create_psbt#516
Open
ValuedMammal wants to merge 14 commits into
Open
Conversation
`TxOrdering` is made generic by exposing the generic from `TxSort` function. This means we're not limited to ordering lists of only `TxIn` and `TxOut`, which will be useful for sorting inputs/outputs of a `bdk_tx::Selection`. We use bitcoin `TxIn` and `TxOut` as the default type parameter to maintain backward compatibility.
We add the `psbt::params` module along with new types including `PsbtParams` and `SelectionStrategy`. `PsbtParams` is mostly inspired by `TxParams` from `tx_builder.rs`, except that we've removed support for `policy_path` in favor of `add_assets` API. `PsbtParams<C>` contains a type parameter `C` indicating the context in which the parameters can be used. Methods related to PSBT creation exist within the `CreateTx` context, and methods related to replacements (RBF) exist within the `ReplaceTx` context. In `lib.rs` re-export everything under `psbt` module. - deps: Add `bdk_tx` 0.2.0 to Cargo.toml
We use the new `PsbtParams` to add methods on `Wallet` for creating PSBTs, including RBF transactions. `Wallet::create_psbt` and `Wallet::replace_by_fee` each have no-std counterparts that take an additional `impl RngCore` parameter. Also adds a convenience method `replace_by_fee_and_recipients` that exposes the minimum information needed to create an RBF. This commit re-introduces the `Wallet::insert_tx` API for adding newly created transactions to the wallet. Added `Wallet::transactions_with_params` that allows customizing the internal canonicalization logic. Added errors to `wallet::errors` module: - `CreatePsbtError` - `ReplaceByFeeError`
Added unit test to `psbt/params.rs` - `test_replace_params` To tests/add_foreign_utxo.rs added - `test_add_planned_psbt_input` To tests/psbt.rs added - `test_create_psbt` - `test_create_psbt_insufficient_funds_error` - `test_create_psbt_maturity_height` - `test_create_psbt_cltv` - `test_create_psbt_cltv_timestamp` - `test_create_psbt_csv` - `test_replace_by_fee_and_recpients` - `test_replace_by_fee_replaces_descendant_fees` - `test_replace_by_fee_confirmed_tx_error` - `test_replace_by_fee_no_inputs_from_original` - `test_create_psbt_utxo_filter` Plus several Sequence fallback and override scenarios - `test_create_psbt_fallback_sequence_applied_to_coin_selected_input` - `test_create_psbt_fallback_sequence_skipped_for_csv_input` - `test_create_psbt_sequence_override_manually_selected_input` - `test_create_psbt_sequence_override_takes_precedence_over_fallback` - `test_create_psbt_sequence_override_csv_conflict_returns_error` To tests/wallet.rs added - `test_spend_non_canonical_txout` - `test-utils`: Add `insert_tx_anchor` test helper for adding a transaction to the wallet with associated anchor block.
…ansaction>> The empty txs case is now caught in `replace_by_fee_with_rng`, which returns `ReplaceByFeeError::NoOriginalTransactions` when `params.replace` is empty. Adds a test in `tests/psbt.rs` covering the error path.
Adds two `CreatePsbtError` variants to cover distinct failure modes
when building a PSBT:
- `NoRecipients`: no recipients were added, or `drain_wallet` was set
without an explicit `change_script`.
- `AllOutputsBelowDust`: after coin selection the only output fell
below dust and was dropped to fees, leaving the transaction with
zero outputs.
Early-exit guards in `create_psbt_with_rng` and `replace_by_fee_with_rng`
return `NoRecipients`. The post-selection guard in `create_psbt_from_selector`
returns `AllOutputsBelowDust`.
Tests:
- `test_create_psbt_no_recipients_error`
- `test_create_psbt_drain_wallet_change_below_dust_error`
- `test_replace_by_fee_drain_wallet_change_below_dust_error`
- Move `add_planned_input` to `impl PsbtParams<CreateTx>`. It was previously available on `PsbtParams<C>` (all contexts), allowing inputs to be erroneously registered after the state transition. - Fix `replace()` to preserve pre-registered planned inputs. A `Transaction` cannot reconstruct `Input` metadata (psbt fields, satisfaction weight, etc.), so planned inputs must be added before calling `replace_txs`. We remove any planned input whose `prev_txid` is directly in the replacement set. - Add `ReplaceByFeeError::ConflictingInput(OutPoint)` in `replace_by_fee_with_rng` after computing the full `to_replace` set, and validate every manually-selected input against it. - Add `test_replace_tx_with_planned_input`, `test_replace_strips_conflicting_planned_input`, and `test_replace_by_fee_conflicting_input_descendant`.
Shuffling the input candidates now occurs only in the case that SingleRandomDraw is the chosen selection strategy. As such, the extra calls to `shuffle_slice` can be removed.
`bdk_tx` is now an optional dependency controlled by the new `bdk-tx` feature. All `create_psbt`/`replace_by_fee` surface area is gated behind `cfg(all(bdk_wallet_unstable, feature = "bdk-tx"))`. Enabling the `bdk-tx` feature without also setting `--cfg bdk_wallet_unstable` in RUSTFLAGS is a compile error with a useful error message. The justfile and CI are updated to pass the `bdk_wallet_unstable` flag in order to test all features. All `create_psbt` and `replace_by_fee` tests are consolidated into a new `tests/create_psbt.rs` gated by `bdk_wallet_unstable`. `.gitignore` is updated to exclude a local `.cargo/config.toml`, and an Unreleased CHANGELOG entry documents the opt-in requirement for users.
2 tasks
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #516 +/- ##
==========================================
+ Coverage 81.15% 81.71% +0.55%
==========================================
Files 24 25 +1
Lines 5552 6438 +886
Branches 247 290 +43
==========================================
+ Hits 4506 5261 +755
- Misses 970 1082 +112
- Partials 76 95 +19
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
This PR introduces
Wallet::create_psbtandWallet::replace_by_fee- a new PSBT construction API built on top ofbdk-tx. This is a second attempt at integrating the planning module that started with #297. The scope is mostly the same and incorporates a number of improvements noted on #297. Notably the entire surface area is gated behind two compile flags.flags:
bdk-txCargo feature--cfg bdk_wallet_unstablerustc flagEnabling
bdk-txwithout also passingbdk_wallet_unstableis a compile error with a clear diagnostic. This allows us to ship the API for early adopters while reserving the right to break it in a minor release.Users can opt in by adding the following to your project's
.cargo/config.toml:and enable the feature in
Cargo.toml:New public API
Wallet::create_psbtWallet::create_psbt_with_rngWallet::replace_by_feeWallet::replace_by_fee_with_rngPsbtParams<C>CisCreateTxorReplaceTx/RbfSelectionStrategyAll,SingleRandomDraw,LowestFee,CustomCreatePsbtErrorcreate_psbtReplaceByFeeErrorreplace_by_feebdk_txre-exportbdk_txTxOrderingis also generalized toTxOrdering<In, Out>to accommodatebdk-tx's typed input/output types.TxOrdering<In, Out>adds default type parameters(
TxIn,TxOut) that are identical to the previous concrete type, so remainssemver-compatible.
Existing callers that don't use the
Customvariant are unaffected.Differences from #297
create_psbtfor Wallet #297 were trimmed; the public API is narrower and more focused.bdk_txre-export -bdk_wallet::bdk_txis re-exported so callers who needbdk-txtypes directly don't need a separatebdk_txdependency.SelectionStrategy::Allreplacesdrain_wallet- modeling "sweep everything" as a strategy is cleaner than aPsbtParamsoption.SelectionStrategy::Custom- users can supply their own coin-selection algorithm as a closure without having to implement a trait.SingleRandomDrawcorrectness fix - shuffling now only runs whenSingleRandomDrawis active; the extrashuffle_slicecalls are removed.bdk_wallet_unstablecfg gate +bdk-txCargo feature - the fullcreate_psbt/replace_by_feesurface is hidden unless explicitly opted into.Changelog notice
Before submitting