-
Notifications
You must be signed in to change notification settings - Fork 330
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor/use iterators to preselect utxos #1798
base: master
Are you sure you want to change the base?
Refactor/use iterators to preselect utxos #1798
Conversation
There were multiple calls for de-duplication of selected UTxOs. As the test `test_filter_duplicates` shows, there are four possible cases for duplication of UTxOs while feeding the coin selection algorithms. 1. no duplication: out of concern 2. duplication in the required utxos only: covered by the source of `required_utxos`, `Wallet::list_unspent`, which roots back the provided `UTxOs` to a `HashMap` which should avoid any duplication by definition 3. duplication in the optional utxos only: is the only one possible as optional `UTxOs` are stored in a `Vec` and no checks are performed about the duplicity of their members. 4. duplication across the required and optional utxos: is already covered by `Wallet::preselect_utxos`, which avoid the processing of required UTxOs while listing the unspent available UTxOs in the wallet. This refactor changes: - `TxParams::utxos` type to be `HashSet<LocalOutput>` avoiding the duplication case 3, and allowing a query closer to O(1) on avg. to cover duplication case 4 (before was O(n) where n is the size of required utxos). - Moves the computation of the `WeightedUtxos` to the last part of UTxO filtering, allowing the unification of the computation for local outputs. - Removes some extra allocations done for helpers structures or intermediate results while filtering UTxOs. - Allows for future integration of UTxO filtering methods for other utilities. - Adds more comments for each filtering step. With these changes all four cases would be covered, and `coin_selection::filter_duplicates` would be no longer needed.
Hey @nymius, does this actually fix something or is this purely a refactor? Note that we want to redo the tx building / creating logic to use |
// only process optional UTxOs if manually_selected_only is false | ||
.take_while(|_| !params.manually_selected_only) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you are trying to be too fancy here. It'll be easier to read if we use an if statement and have may_spend
as a separate variable.
let may_spend = if params.manually_selected_only {
// This will be empty
} else {
self.list_unspent()
// etc...
};
Hi @evanlinjin. Yes, maybe I went to far with the changes, still, it fixes the duplicate issue I open in #1794 by using a Then, about the refactor: The research of the code push me to isolate the pre selection steps as items on a checklist and that's why It ended up as a refactor. My idea is to further isolate each filter in their own iterator adaptor (a separated function for each one) that consumes The heavy use of iterators came for trying to avoid the allocation of helpers, like I envisioned something like this: let optional_utxos = self
.list_unspent()
.check_are_not_already_manually_selected()
.check_are_not_unspendable()
.check_confirmed_only_if_RBF()
.check_is_local_utxo()
.check_is_mature_if_coinbase();
// then
let (required, optional) = optional_utxos.chain(required_utxos.iter().clone())
.get_weighted_utxos()
.chain(foreign_utxos.iter().clone())
.apply_custom_validation_for_all_tx_inputs()
.split_utxos_in_required_and_optional() Discussing this today with @ValuedMammal, I decided to do the following changes:
If we don't agree on the above, I propose the following alternatives:
|
There is no case in which current_height is None within create_tx.
Manually selected utxos are already available. We don't need a method to hand them out.
05ac09c
to
e42b5aa
Compare
Description
There were multiple calls for de-duplication of selected UTxOs in
Wallet::create_tx
: (1) and (2).As the test
test_filter_duplicates
shows, there are four possible cases for duplication of UTxOs while feeding the coin selection algorithms.required_utxos
,Wallet::list_unspent
, which roots back the providedUTxOs
to aHashMap
which should avoid any duplication by definitionUTxOs
are stored in aVec
and no checks are performed about the duplicity of their members.Wallet::preselect_utxos
, which avoid the processing of required UTxOs while listing the unspent available UTxOs in the wallet.This refactor does the following:
TxParams::utxos
type to beHashSet<LocalOutput>
avoiding the duplication case 3required_utxos
,Wallet::list_unspent
comes from aHashMap
which should avoid duplication by definition.WeightedUtxos
to the last part of UTxO filtering, allowing the unification of the computation for local outputs.foreign_utxos
, which should include a provided satisfation weight to use them effectively, andutxos
, manually selected UTxOs for which the wallet can compute their satisfaction weight without external resources.With these changes all four cases would be covered, and
coin_selection::filter_duplicates
is no longer needed.Fixes #1794.
Notes to the reviewers
I haven't added test because the refactor doesn't include new features and the duplication improvements are based on the nature of structs that avoid duplication per se (
HashMap
,HashSet
).Changelog notice
No changes to public APIs.
Checklists
cargo fmt
andcargo clippy
before committingThis pull request breaks the existing APINoI've added tests to reproduce the issue which are now passingI haven't added any new tests