-
Notifications
You must be signed in to change notification settings - Fork 322
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
Remove BIP 69 sorting #534
Comments
+1. Thanks for bringing this up. Before depreciating BIP69 I think we should make it possible to set the rng for shuffling so you still have a deterministic sorting option. I'd like this so it's still easy to have two wallets come up with the same input/output ordering. |
For context BDK currently defaults to Lines 648 to 663 in b1346d4
|
@LLFourn Do you need to have deterministic random sorting for testing or are there other uses for it? If only for Lines 665 to 691 in b1346d4
|
I'm not sure what @LLFourn was specifically looking for, but that makes sense - if you have some two-party protocol (like lightning, but lightning has a different, worse, way of doing this) where two nodes have to agree on a transaction and just want to exchange signatures, you need some way to sort the inputs+outputs such that they both agree, without having to bother communicating. You can do something deterministic (like BIP 69) but its much better to instead take some random secret value that both parties already have and use that to seed your RNG. Of course you have to ensure your RNG then generates deterministic output given the seed (I'm not sure if the |
I need it for the scenario @TheBlueMatt mentioned.
Right I currently use BIP69 in https://gun.fun because it's a simple way of agreeing on an order for a dual funded transaction (privacy is not relevant here atm since tx is distinguishable for other reasons). Good point on ensuring it's API stable. Looking at the current implementation of shuffle it's 3 lines of code so should be easy enough to roll our own. Just looking around it looks like this deterministic sorting of transactions based on secret data is something that people have been wanting: https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2018-October/016457.html. Perhaps if the person who takes this issue feels so inspired they could come up with something that might be easily specifiable (might not be the way rand does it). |
Agreed that we can deprecate it to show a warning that it should not be used, but I'm not sure I would remove it completely anytime soon. The way I see BDK is not just as a library to build wallets today, but also as a "swiss army knife" that can do anything. Like, if you have a 5 yr old project and you want to port it to BDK, you should be able to do that. So in theory anything that has ever been used should be supported here (unless it's completely broken, but I don't think BIP69 is). But I agree that we should discourage new users from building something that relies on it. For the "custom sorting" scenario, I'm wondering if instead of an |
Right, here is where we (strongly) disagree. BIP 69 is completely and totally broken, IMO. Absent use-cases like @LLFourn's, it has absolutely no place in a Bitcoin wallet whatsoever. |
Permanent depreciation sounds like a good solution. BIP69 can be useful in some odd cases but asking you to suppress a warning if you actually find yourself in a situation where it is useful seems reasonable.
I really like this idea. Actually a custom let shared_secret = ...;
let cmp_fn = |a,b| {
sha256(shared_secret, a).cmp(sha256(shared_secret, b))
}; This will give the same ordering for both parties if they both have |
Greetings everyone, 👋 Can I take this up ? I'll also be glad to be guided a bit. |
@Eunoia1729 Go for it! Probably the best approach right now is to do what @afilini suggested and allowing a custom comparison function. So I guess this means adding a
I think that makes sense but don't be surprised if you find a better way of doing it :) |
Hey @LLFourn, I was trying to implement it the way you suggested but that would require changing the derived traits since the current ones (Eq/Ord/Hash/Copy straight up won't work, Clone might work but would be weird, Debug will be pointless?) won't work if it's a Fn. It gets really complicated to do it that way, and I don't think it's possible without some major changes. What if we do it like say,
This way, either the input or output can be added (if they aren't added, it behaves like |
@fadedcoder do we actually need those derives for anything? I wouldn't have thought so. Try removing them. If we need What you suggested would work but it'd be suboptimal. |
@LLFourn Yeah that sounds good. Also I think it would be better to use non immutable Fn since if we add mutability with an |
Ok I see your point. If it does need to be an |
@Eunoia1729 have you started looking into this issue? If so can you help @fadedcoder with testing/review for #556 ? |
@notmandatory Yes, I was working on it but paused when a PR was opened. Sure, will be happy to help with testing/review ! |
@rustaceanrob are you working on this? |
…e BIP69 3bee563 refactor(wallet)!: remove TxOrdering::Bip69Lexicographic (nymius) e5cb7b2 feat(wallet): add TxOrdering::Custom (FadedCoder) Pull request description: <!-- You can erase any parts of this template not applicable to your Pull Request. --> ### Description Resolves bitcoindevkit#534. Resumes from the work in bitcoindevkit#556. Add custom sorting function for inputs and outputs through `TxOrdering::Custom` and deprecates `TxOrdering::Bip69Lexicographic`. <!-- Describe the purpose of this PR, what's being adding and/or fixed --> ### Notes to the reviewers I tried consider all discussions in bitcoindevkit#534 while implementing some changes to the original PR. I created a summary of the considerations I had while implementing this: ##### Why use smart pointers? The size of enums and structs should be known at compilation time. A struct whose fields implements some kind of trait cannot be specified without using a smart pointer because the size of the implementations of the trait cannot be known beforehand. ##### Why `Arc` or `Rc` instead of `Box`? The majority of the useful smart pointers that I know (`Arc`, `Box`, `Rc`) for this case implement `Drop` which rules out the implementation of `Copy`, making harder to manipulate a simple enum like `TxOrdering`. `Clone` can be used instead, implemented by `Arc` and `Rc`, but not implemented by `Box`. ##### Why `Arc` instead of `Rc`? Multi threading I guess. ##### Why using a type alias like `TxVecSort`? cargo-clippy was accusing a too complex type if using the whole type inlined in the struct inside the enum. ##### Why `Fn` and not `FnMut`? `FnMut` is not allowed inside `Arc`. I think this is due to the `&mut self` ocupies the first parameter of the `call` method when desugared (https://rustyyato.github.io/rust/syntactic/sugar/2019/01/17/Closures-Magic-Functions.html), which doesn't respects `Arc` limitation of not having mutable references to data stored inside `Arc`: Quoting the [docs](https://doc.rust-lang.org/std/sync/struct.Arc.html): > you cannot generally obtain a mutable reference to something inside an `Arc`. `FnOnce` > `FnMut` > `Fn`, where `>` stands for "is supertrait of", so, `Fn` can be used everywhere `FnMut` is expected. ##### Why not `&'a dyn FnMut`? It needs to include a lifetime parameter in `TxOrdering`, which will force the addition of a lifetime parameter in `TxParams`, which will require the addition of a lifetime parameter in a lot of places more. **Which one is preferable?** <!-- In this section you can include notes directed to the reviewers, like explaining why some parts of the PR were done in a specific way --> ### Changelog notice - Adds new `TxOrdering` variant: `TxOrdering::Custom`. A structure that stores the ordering functions to sort the inputs and outputs of a transaction. - Deprecates `TxOrdering::Bip69Lexicographic`. <!-- Notice the release manager should include in the release tag message changelog --> <!-- See https://keepachangelog.com/en/1.0.0/ for examples --> ### Checklists #### All Submissions: * [ ] I've signed all my commits * [x] I followed the [contribution guidelines](https://github.com/bitcoindevkit/bdk/blob/master/CONTRIBUTING.md) * [x] I ran `cargo fmt` and `cargo clippy` before committing #### New Features: * [x] I've added tests for the new feature * [ ] I've added docs for the new feature Top commit has no ACKs. Tree-SHA512: 0d3e3ea9aee3a6c9e9d5e1ae93215be84bd1bd99907a319976517819aeda768a7166860a48a8d24abb30c516e0129decb6a6aebd8f24783ea2230143e6dcd72a
BIP 69 input+output sorting was a very bad idea from day one (it relies on the assumption that all wallets sort their inputs+outputs according to BIP 69 - something that will never happen - in order to provide privacy). It has no place in BDK. Instead, transaction input and output ordering should simply be randomized, making it much harder for a transaction classifier to sort transactions.
The text was updated successfully, but these errors were encountered: