Skip to content

Preserve insertion order of manually selected utxos if TxOrdering::Untouched#262

Merged
oleonardolima merged 3 commits intobitcoindevkit:masterfrom
nymius:fix/tx_build_should_not_change_order_of_insertion_with_vector
Jul 1, 2025
Merged

Preserve insertion order of manually selected utxos if TxOrdering::Untouched#262
oleonardolima merged 3 commits intobitcoindevkit:masterfrom
nymius:fix/tx_build_should_not_change_order_of_insertion_with_vector

Conversation

@nymius
Copy link
Copy Markdown
Contributor

@nymius nymius commented Jun 10, 2025

Description

On my attempt to fix bitcoindevkit/bdk#1794 in bitcoindevkit/bdk#1798, I broke the assumption that insertion order is preserved when TxBuilder::ordering is TxOrdering::Untouched. Some users are relying in this assumption, so here I'm trying to restore it back, without adding a new dependency for this single use case like #252, or creating a new struct just to track this.

In this fourth alternative solution I'm going back to use Vec to store the manually selected UTxOs.

I was reluctant to do it in this way because HashMap seems a better solution giving its property of avoiding duplicates, but as we also want to keep the secuential nature of the insertion of UTxOs in TxBuilder, here is an alternative aligned with that principle.

May replace #252
May replace #261 .
Fixes #244

Notes to the reviewers

Also, as I was working on this, I came back to the following tests:

  • test_prexisting_foreign_utxo_have_no_precedence_over_local_utxo_with_same_outpoint
  • test_prexisting_local_utxo_have_precedence_over_foreign_utxo_with_same_outpoint

Motivated during the implementation and review of bitcoindevkit/bdk#1798.

Which required the underlying structure to also hold the properties of no duplication for manually selected UTxOs, as the structures were accessed directly for these cases.

The test tries to cover the case when there are two wallets using the same descriptor, one tracks transactions and the other does not. The first passes UTxOs belonging to the second one and this one creates transactions using the add_foreign_utxo interface.
In this case it was expected for any LocalUtxo of the offline wallet to supersede any conflicting foreign UTxO. But, the simulation of this case went against the borrowing constraints of rust.
By how costly was to reproduce this behavior for me in the tests, I would like to have second opinions in the feasibility of the test case.

Changelog notice

No public APIs are changed by these commits.

Checklists

Important

This pull request DOES NOT break the existing API

  • I've signed all my commits
  • I followed the contribution guidelines
  • I ran cargo +nightly fmt and cargo clippy before committing
  • I've added tests for the new code
  • I've expanded docs addressing new code
  • I've added tests to reproduce the issue which are now passing
  • I'm linking the issue being fixed by this PR

@coveralls
Copy link
Copy Markdown

coveralls commented Jun 10, 2025

Pull Request Test Coverage Report for Build 15949866545

Details

  • 109 of 120 (90.83%) changed or added relevant lines in 2 files are covered.
  • 14 unchanged lines in 5 files lost coverage.
  • Overall coverage decreased (-1.1%) to 84.455%

Changes Missing Coverage Covered Lines Changed/Added Lines %
wallet/src/wallet/tx_builder.rs 83 84 98.81%
wallet/src/wallet/mod.rs 26 36 72.22%
Files with Coverage Reduction New Missed Lines %
wallet/src/descriptor/dsl.rs 1 95.34%
wallet/src/wallet/changeset.rs 2 85.0%
wallet/src/descriptor/policy.rs 3 79.07%
wallet/src/descriptor/template.rs 4 98.04%
wallet/src/wallet/mod.rs 4 81.03%
Totals Coverage Status
Change from base Build 15719064446: -1.1%
Covered Lines: 6427
Relevant Lines: 7610

💛 - Coveralls

@notmandatory notmandatory moved this to Discussion in BDK Wallet Jun 12, 2025
@notmandatory notmandatory added this to the Wallet 2.1.0 milestone Jun 12, 2025
@notmandatory notmandatory moved this from Discussion to In Progress in BDK Wallet Jun 12, 2025
Comment thread wallet/src/wallet/tx_builder.rs Outdated
@nymius nymius force-pushed the fix/tx_build_should_not_change_order_of_insertion_with_vector branch from 7f16781 to b1436ae Compare June 23, 2025 15:00
@nymius nymius changed the title Fix/tx build should not change order of insertion with vector [FIX] Preserve insertion order of manually selected utxos Jun 23, 2025
@nymius nymius changed the title [FIX] Preserve insertion order of manually selected utxos Preserve insertion order of manually selected utxos if TxOrdering::Untouched Jun 23, 2025
@nymius nymius force-pushed the fix/tx_build_should_not_change_order_of_insertion_with_vector branch from b1436ae to dde0b3e Compare June 23, 2025 15:15
@nymius nymius marked this pull request as ready for review June 23, 2025 15:22
@nymius nymius requested a review from ValuedMammal June 23, 2025 15:24
Comment thread wallet/src/wallet/tx_builder.rs Outdated
Comment thread wallet/src/wallet/tx_builder.rs Outdated
Comment thread wallet/tests/wallet.rs Outdated
@ValuedMammal
Copy link
Copy Markdown
Collaborator

I would like to have second opinions in the feasibility of the test case.

Since our logic is meant to enforce the precedence of local utxos, it makes sense to keep the test, but I agree there could be a simpler, easy to maintain version of it. ValuedMammal/bdk_wallet@49b5cef

Copy link
Copy Markdown
Collaborator

@ValuedMammal ValuedMammal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the rest of the codebase I want to stick with the "UTXO" style acronym.

@notmandatory notmandatory added the bug Something isn't working label Jun 25, 2025
@nymius nymius force-pushed the fix/tx_build_should_not_change_order_of_insertion_with_vector branch 2 times, most recently from 048daa6 to d6d204b Compare June 25, 2025 18:29
@nymius
Copy link
Copy Markdown
Contributor Author

nymius commented Jun 25, 2025

Thanks for the review!
I think I have addressed all the comments.
I just changed the occurrences of {utxos,UTxOs} in the lines related to the changes I did, to avoid cluttering the diff with other lines not related to the present PR.

@nymius nymius requested a review from ValuedMammal June 25, 2025 18:34
Copy link
Copy Markdown
Collaborator

@ValuedMammal ValuedMammal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK d6d204b

@notmandatory notmandatory moved this from In Progress to Needs Review in BDK Wallet Jun 26, 2025
Copy link
Copy Markdown
Contributor

@oleonardolima oleonardolima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK

I left a question and a single nit, but overall it looks good to me! Agree with the new version of test suggested by VM's, it looks much better.

Comment thread wallet/src/wallet/tx_builder.rs
Comment thread wallet/src/wallet/mod.rs Outdated
nymius and others added 3 commits June 28, 2025 21:50
When TxBuilder::ordering is TxOrdering::Untouched, the insertion order
of recipients and manually selected UTxOs should be preserved in
transaction's output and input vectors respectively.

Fixes bitcoindevkit#244
@nymius nymius force-pushed the fix/tx_build_should_not_change_order_of_insertion_with_vector branch from d6d204b to 0522114 Compare June 29, 2025 00:51
Copy link
Copy Markdown
Collaborator

@ValuedMammal ValuedMammal left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reACK 0522114

Copy link
Copy Markdown
Contributor

@oleonardolima oleonardolima left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 0522114

@oleonardolima oleonardolima merged commit b925402 into bitcoindevkit:master Jul 1, 2025
20 checks passed
@github-project-automation github-project-automation Bot moved this from Needs Review to Done in BDK Wallet Jul 1, 2025
@nymius nymius deleted the fix/tx_build_should_not_change_order_of_insertion_with_vector branch July 1, 2025 19:05
ValuedMammal added a commit that referenced this pull request Apr 22, 2026
…quired UTXOs first

8a5e763 test(tx_builder): Add `test_add_utxo_final_outpoint_retained` (valued mammal)
0b5d927 test(wallet): Add `test_tx_ordering_untouched_preserves_insertion_ordering_bnb_success` (valued mammal)
e020391 fix(coin_selection): `calculate_cs_result` returns the required UTXOs first (valued mammal)

Pull request description:

  ### Description

  Follow-up to #262 that addresses transaction input ordering when BnB finds a solution.

  Previously `calculate_cs_result` produced a CoinSelectionResult by appending the required UTXOs onto the selected ones, which changed the expected order of transaction inputs.

  `calculate_cs_result` now returns the required UTXOs before the newly selected ones. This behavior aligns with the expectation that the order of manually selected inputs should be preserved in the final transaction whenever `TxOrdering::Untouched` is specified.

  For related discussion refer to #244 (comment).

  ### Changelog notice

  Fixed

  - wallet: Fixed order of selected UTXOs for `BranchAndBoundCoinSelection`, required UTXOs come first

  ### Checklists

  #### All Submissions:

  * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md)

  #### Bugfixes:

  * [x] I've added tests to reproduce the issue which are now passing
  * [x] I'm linking the issue being fixed by this PR

ACKs for top commit:
  110CodingP:
    ACK [`8a5e763`](8a5e763).

Tree-SHA512: 4ebf33f7d1fe6e6dcfff89e218aeefcec92ae8ae78c2589d7f496b433991122f48100be38ffa52b8fc2d67feb679d567a707dea8681810167eac1a6a04f9dcc0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

TxOrdering::Untouched no longer ensures the order of tx input Utxo filtering done twice (presumed redundantly) while creating transaction

5 participants