-
Notifications
You must be signed in to change notification settings - Fork 279
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
[wallet] Transaction creation overhaul #258
[wallet] Transaction creation overhaul #258
Conversation
Converted to a draft since I forgot to fix stuff behind feature flags! |
0ebce97
to
826b996
Compare
Because I changed the testutils package I had to make the the dependency path relative (826b996) for it to work. Does this create a problem when publishing it? This is ready for review now. |
e780c5d
to
104b802
Compare
I haven't finished reading the code yet, but here are just a few things I've noticed that might need some more attention:
Then another question, not because it's something that should be fixed but because I wanted to understand this better: is there a specific reason why you chose |
@afilini thanks for taking a look.
Just to be clear, it is implausible to have an api that consumes Of course we could just say that you always have to assign the builder and make let mut builder = wallet.build_tx();
builder.add_recipient(addr.script_pubkey(), 50_000)
.add_utxo(my_utxo)?
.manually_selected_only();
let (psbt, details) = builder.finish()?; I am fond of the efficiency of the current API but I do see that the above may be better -- it's not like your codebase is going to be full of
See above. If they return
IMO as a user having methods that are infallible but return
As I now recall the problem with Perhaps it could be changed to
I was thinking of actually removing |
Yeah I totally agree with that, my point was actually slightly different: I was thinking about the fact that fallible methods could (when they do fail) leave the So basically I was suggesting that switching back to using Having thought about it a bit more I think I agree with you now on the benefits of the mutable reference: yesterday I was just dumping out everything I had in mind and one thing was "if we capture the value and don't return it, we don't have to worry about inconsistencies", and it felt like a good tradeoff. In fact now I see this more as a downside, because I can definitely see a few use-cases where you'd like to try doing something, but keep going if that fails.
Yes, this seems like a good compromise. As an alternative I guess we could have two methods that do the same thing, one which is more suitable to be chained (takes a reference) and one to use when you've assigned the variable somewhere, which takes its ownership. But I don't know, maybe it would end up being even more confusing...
Yeah I think it's likely that over time we'll keep adding more methods that can fail or even update some of the ones we have (
Yes, I also like this design better compared to the old
Makes sense, I like this! |
In my rush yesterday I forgot to respond to:
This is actually a brain error. Thanks for catching it. I was trying to preserve insertion and make it a set. Obviously https://github.com/bitcoindevkit/bdk/blob/master/src/wallet/mod.rs#L2855 Notice how the So I suggest:
There's actually one weird trick that let's you do this but keep the same name for the method: https://github.com/dtolnay/case-studies/tree/master/autoref-specialization#background-method-resolution But I think keeping things simpler is better. I doubt that assigning the builder will turn out to be a real pain point for anyone. |
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.
- Just make coin_selection an argument to .finish() or build_tx() and build_fee_bump() so there is no ambiguity in the order.
We could also add a second build function, something like
let (psbt, details) = wallet.build_tx_with_coin_selection(AlwaysSpendEverything)
.add_recipient(to_address.script_pubkey(), 50_000)
.finish()?;
Actually there is deduplication already, here it is in the current Lines 703 to 712 in a95a9f7
As always, not sure if that's the best thing to do, but it seemed reasonable when I wrote it. If there aren't really any downsides to this I guess we should stick with this behavior (and maybe document it?).
That's really neat! But yeah, I think I agree with you: let's keep it simple. If we see people opening bug reports or complaining in general because of the panic in |
I think I still prefer the Though, in this example, I can also see that it'd be nice to be able to construct a tx after the builder is updated, to show things likes size, fees, etc. @LLFourn maybe we should make the builder |
c234be1
to
d1f2dbe
Compare
d1f2dbe
to
c7e7b15
Compare
c7e7b15
to
748882a
Compare
I've pushed changes to require the builder to be assigned and then make
I also pushed changes to preserve this behavior but upon further reflection I don't really like it. I think we should consider changing the behavior. Consider the following rules:
The implication of these two rules is that What do you think?
yes. |
748882a
to
7a3924e
Compare
Due to brain malfunction I made utxos into a BTree. This made a test pass but is incorrect. The test itself was incorrect as per comment in bitcoindevkit#258 (comment) So I (1) reverted utxos back to a Vec, (2) fixed the test and expanded the comment in the test.
e9a8633
to
a1ac347
Compare
Due to brain malfunction I made utxos into a BTree. This made a test pass but is incorrect. The test itself was incorrect as per comment in bitcoindevkit#258 (comment) So I (1) reverted utxos back to a Vec, (2) fixed the test and expanded the comment in the test.
And make Wallet Debug while I'm at it.
To replace the previously existing ".utxos"
a1ac347
to
ff10aa5
Compare
I've pushed changes to:
|
Thanks, that looks really good! Reviewing it now.
I'd actually just keep it as a shortcut, I think some people might expect it to exist. |
71f930b
to
dbf8cf7
Compare
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.
The code looks really good, sorry I didn't notice those (minor) issues in the CHANGELOG before :(
@afilini Thanks. Fixed nits and turned on trailing whitespace detection for the future :) |
HAPPY NEW YEAR!
Background
While trying to do #114 I was making a mess.
This PR is an attempt to tackle the problems with the internals of transactions creation that made the PR difficult.
In addition it fixes #251.
Major Changes/Improvements
TxBuilder
s are not created directly but throughbuild_tx
andbuild_fee_bump
methods onWallet
. To finally create the tx you call.finish()
on the builder.bump_fee
is gone!TxBuilder
methods take&mut self
rather thanself
-- makes building transactions more ergonomic since you can use chaining or assign the tx builder and just make calls on it.TxBuilder.add_utxo
now retrieves UTXO data and stores it. If the UTXO doesn't exist then you get an error early.add_utxo
early #251 and is the main change intended to make Add foreign outputs toTxBuilder
#114 easier since it allows normalizing the local and foreign UTXOs into the same list early.TxBuilder.utxos
has been removed in favor of repeatedly callingadd_utxo
(which is now more ergonomic because of the&mut self
change).TxBuilder.utxos
has been replaced withTxBuilder.add_utxos
which doesn't overwrite the existing utxos but allows you to add a list on top the existing list.TxBuilder
's internal list of UTXOs is now stored as a BTreeMap to prevent duplicates.wallet.get_utxo
andwallet.get_descriptor_for_keychain
are now exposed publicly.pub(crate)
only but I think they are fine to be public.[cfg(test)]
only methodreceived_tx
that was used internally for testing is now a macro so it can be used from doctests. It's calledpopulate_test_db
. Severalno_run
tests can now be run. See fb167ad and 5fad5e2 .TxBuilder
is nowClone
.Wallet
is nowDebug
.This opens up the door to fixing the following issues:
add_utxo
.build_fee_bump
works internally.utxos
Vec
.Notes to the reviewers
This is based of #255 so merge after that.
Sorry for the very large PR I wasn't able to nicely separate the external and internal changes easily.
Checklists
All Submissions:
cargo fmt
andcargo clippy
before committingNew Features:
CHANGELOG.md