-
Notifications
You must be signed in to change notification settings - Fork 331
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
bdk v1.0.0-alpha.0 #793
bdk v1.0.0-alpha.0 #793
Conversation
bf2ba37
to
cbe573e
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.
I still need to finish a couple of files but since it's taking me so long I'll start by posting those comments
src/wallet/mod.rs
Outdated
if block.header.prev_blockhash != exp_hash { | ||
panic!("block hash does not match!"); | ||
} | ||
} |
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 guess otherwise you should check it's genesis block
src/blockchain/esplora.rs
Outdated
/// transaction output along with the update. After `stop_gap` script pubkeys have no related | ||
/// transactions it terminates (or if the iterator is exhausested). | ||
/// | ||
/// `parallel_requests` indicates that the client may make that may **additional** requests in |
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.
"that the client may make additional requests"
src/blockchain/esplora.rs
Outdated
}) | ||
.collect::<Vec<_>>(); | ||
|
||
let n_handles = handles.len(); |
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.
This can be moved down i guess? n_handles
is not used in the loop
src/blockchain/esplora.rs
Outdated
}) | ||
.collect::<Vec<_>>(); | ||
|
||
if !blocks_at_end.contains(&tip_at_start) { |
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.
Esplora returns the last 10 blocks, so in theory here we should also make sure that the height of tip_at_start
is in this range, otherwise we need to fetch more blocks.
src/blockchain/esplora.rs
Outdated
}) | ||
.collect::<Vec<_>>(); | ||
|
||
if !blocks_at_end.contains(&tip_at_start) { |
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.
Same as above
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 an initial review, I still need to look at half of src/wallet/mod.rs
(I reviewed until before apply_update
) and a bunch of other files. I'm posting this half-baked review so that you can start replying to all my questions (sorry, lol)
/// Return the address for a specific descriptor index and reset the current descriptor index | ||
/// used by `AddressIndex::New` and `AddressIndex::LastUsed` to this value. | ||
/// | ||
/// Use with caution, if an index is given that is less than the current descriptor index | ||
/// then the returned address and subsequent addresses returned by calls to `AddressIndex::New` | ||
/// and `AddressIndex::LastUsed` may have already been used. Also if the index is reset to a | ||
/// value earlier than the [`crate::blockchain::Blockchain`] stop_gap (default is 20) then a | ||
/// larger stop_gap should be used to monitor for all possibly used addresses. | ||
Reset(u32), |
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.
Could you expand a bit on why is Reset being removed?
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 reason is to create the invariant that every UTXO you have must have a derivation index less than or equal to your current derivation index. Clearly this cannot hold if you allow "resetting" your derivation index. Why do we want this invariant? It simplifies API and internals. There is no longer two indexes you are tracking: (i) where you are cached up to, (ii) where you are giving out addresses at. You just have one number which does handles both things.
However we should allow for "trimming" your derivation index down to your last active index. This will be needed in order to do stop_gap
style syncing with things like CBF and rpc
block streaming. The algorithm would be to set your derivation index to last_active_index + stop_gap
before applying each block. Then when you've reached the tip you can trim to the last_active_index
and the wallet becomes operational.
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.
Personally I think we should re-enable this feature to reset to the largest of:
- First unused index
- Parameter in
Reset(param)
It shouldn't be complicated to implement with the KeychainTxOutIndex
API.
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 we would need to "unreveal" method in KeychainTxOutIndex
first I think. I still find this very questionable. Why would you reveal an address and then not actually reveal it. In any case this feature shouldn't be done as an AddressIndex
.
src/wallet/mod.rs
Outdated
pub enum ApplyUpdateErr { | ||
/// The data in the update was somehow incompatible with the existing chain's data. | ||
Chain(UpdateFailure), | ||
/// The update was compatible but it was missing **full** transactions for some txids it found. |
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 to make sure that I understand: this error is thrown if the Update is containing a certain txidA
in the new_txids
, but there's not a transaction with txid equal to txidA
in the blocks between the last valid checkpoint and new_tip
. Is that right?
Edit: I tried to read apply_update
and concluded that I'm probably wrong
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.
It is thrown when we are told there is a relevant txid
in some block but we haven't provided the actual transaction. This comes up with electrum which first returns you a list of txids
which you would go and turn into an update. The wallet would then tell you which transactions it actually needs you to download with that error. You go and fetch them and re-apply it.
src/wallet/mod.rs
Outdated
pub fn list_unspent(&self) -> Vec<LocalUtxo> { | ||
self.spk_tracker | ||
.iter_unspent(&self.sparse_chain, &self.tx_graph) | ||
.map(|((keychain, _), txo)| LocalUtxo { |
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.
This reminds me: the 1.0 release is a good opportunity to rename LocalUtxo
to LocalTxOut
:)
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.
Note i didn't do this here. I think it's possible we could get rid of this type in favor of using a bdk_chain
one.
src/wallet/mod.rs
Outdated
if self.sparse_chain.transaction_height(tx.txid()).is_some() { | ||
continue; | ||
} |
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.
This checks seems relatively cheap, maybe it should be done first, before the match?
Just pushed changes to:
|
I'm currently trying wrap my head around how/if this new syncing mechanism could be used to better integrate with LDK. IIUC, the main idea here is that instead of having a monolithic
I think generally a similar scheme could be used to update the LDK-internal wallet (e.g., via the
Would be interested in any feedback regarding this, in particular whether we could find any abstractions that would allow us to further integrate the sync mechanisms or the wallets themselves, for that matter. |
Can these abstraction be defined in LDK or do you think they need to be in BDK?
I added an issue for this: LLFourn/bdk_core_staging#84. Currently we don't require you pass a descriptor (at least over at the bdk_core repo). You just pass in an iterator of script pubkeys you are interested in. I think we can add to that iterators of outpoints and txids to that.
We have designed the internals to allow this. I created an issue (LLFourn/bdk_core_staging#85) for someone to actually do the work to include the all this info. Currently (though not in this PR yet) we only include the confirmation height as "additional data" (and sometimes the confirmation time as well).
I don't understand exactly this requirement but our update logic makes it hard to get this wrong I hope. There's an issue to make the ordering even more picky LLFourn/bdk_core_staging#70 but I'm not sure if this addresses your concern.
Thanks for making this comment and apologies for the late reply. I'm going to be updating this PR soon so you can have a look at the state of the art. |
Hm, I think BDK would need to provide some kind of API that we can work with, e.g., some trait-based interface that we could implement.
Nice, looking forward to these!
Yeah, I think the details of the implementation should lie on our side, but the main point w.r.t. BDK would be that the interface would give us the updates in topological chain order.
Sounds good, thank you! :) |
e681ece
to
46dd898
Compare
Status update. Here's the scope of the PR and where we are on it:
So remaining:
There is one issue that should be done in bdk_core staging: LLFourn/bdk_core_staging#114 |
795d55a
to
a8291b8
Compare
a8291b8
to
5b483b8
Compare
5b483b8
to
7e8f849
Compare
Status update:
Remaining for
|
Just reading back @tnull's comments:
Ok so our design does not enforce this: "changesets" can insert transactions that are ancestors of transactions that have already appeared in previous changesets. This will never happen in most workflows (and can be guaranteed never to happen if you update your state purely by applying new blocks sequentially). Other than sending bdk's changesets over to LDK maybe we can just create a custom "update" for it from our own chain data. We store and index a lot of stuff in memory so if the requirement is answering questions like "have these outputs been spent and by what tx" it should be easy. More sophisticated things like "notify me when this output is spent (or is no longer spent)" should be doable as well (but not yet implemented in an easy to consume way). |
One thing I think I forgot to implement is an API to expose |
26ae2ce
to
e67610a
Compare
I've just make the repo into a workspace. Existing The final task for |
d314d9c
to
b603abb
Compare
331fdb7
to
8d56d55
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.
ACK 8d56d55
CI updated, and tests passing. Organization looks good. There are small nits we could still fix but it's good enough for a first alpha release and will be easier to collaborate on additional changes once this PR is merged.
LLFourn is squashing these to get them all signed: Remove useless clippy allow ci: use clippy action [ci] remove check for features=default
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 pushed a commit with some small doc fixes.
ACK bc3e05c
We are not using them, removed in bitcoindevkit#793 more specifically in 3f5a78a NOTE: speculos can be run under Nix - https://github.com/alamgu/speculos/tree/with-nix-build - LedgerHQ/speculos#323
We are not using them, removed in bitcoindevkit#793 more specifically in 3f5a78a NOTE: speculos can be run under Nix - https://github.com/alamgu/speculos/tree/with-nix-build - LedgerHQ/speculos#323
We are not using them, removed in bitcoindevkit#793 more specifically in 3f5a78a NOTE: speculos can be run under Nix - https://github.com/alamgu/speculos/tree/with-nix-build - LedgerHQ/speculos#323
We are not using them, removed in bitcoindevkit#793 more specifically in 3f5a78a NOTE: speculos can be run under Nix - https://github.com/alamgu/speculos/tree/with-nix-build - LedgerHQ/speculos#323
We are not using them, removed in bitcoindevkit#793 more specifically in 3f5a78a NOTE: speculos can be run under Nix - https://github.com/alamgu/speculos/tree/with-nix-build - LedgerHQ/speculos#323
27a63ab chore: typos fixed (Einherjar) Pull request description: ### Description Fixes the typos and remove unused speculos dockerfiles that was done in #1165. Moving these changes into this PR to be merged first. Then, we can rebase #1165 and make it only related to CI and Nix. (Maybe do a big squash 😄) ## Note to Reviewers About the speculos stuff, we are not using them, removed in #793, more specifically in 3f5a78a. ### Changelog notice - Fix typos in codebase and docs - Remove unused CI tests with hardware signer Dockerfiles ### Checklists #### All Submissions: * [x] 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: * [ ] I've added tests for the new feature * [ ] I've added docs for the new feature #### Bugfixes: * [ ] This pull request breaks the existing API * [ ] I've added tests to reproduce the issue which are now passing * [ ] I'm linking the issue being fixed by this PR ACKs for top commit: danielabrozzoni: ACK 27a63ab Tree-SHA512: a01101d0741e2b0e1d1254b5cae670c5a936bb0b89332c102feb57d58d2b9ae995ed4436068b0dc5fae73dbe22431c3143d6e04cdc12eab991bd726cfd2fbe25
8694624 Bump `bip39` to v2.0 (Elias Rohrer) Pull request description: We previously bumped the `bip39` version to 2.0 [in the 0.2X release branch](#875). Back then, bumping it in `master` was [assumed unnecessary](#875 (comment)). It seems this was erroneous, as the current `1.0.1` dependency is present since #793, which was merged before the bump in `release/0.27`. Here, we therefore bump the crate version in `master` after all. ACKs for top commit: notmandatory: ACK 8694624 Tree-SHA512: a109219bc97bb8e965e8b10e72439aa898b710d1d1a154801ce499ad47475a6b23448d85e0de3f306f990573d1fccdae7d587ed41676a01f91d66a719782eae1
We prepare the BDK repo for a major restructuring 🔥. This PR maintains the existing wallet API as much as possible and adds very little.
Things Done
--all-features
now.esplora
APIs changed
sync
method. This is replaced withapply_wallet_scan
.ensure_derived_up_to
which sets your derivation to at least the argument. Unlikeensure_addresses_cached
used to do this will alter what getting a new address gives you.AddressIndex::Reset
is gone. This thing didn't make much sense and is hard to do with the more sane internals we've established. Changing the derivation index changes what script pubkeys the wallet will search so this is dangerous. We plan to add method liketrim_unused
which lowers the derivation index to the highest unused index. Applications must handle giving out old addresses manually now (which I think is good).Unfinished work
u64::MAX
). Inbdk_core
we never got around to doing this but it needs to be done.Notes to the reviewers
Try not to review the actual changes. This PR will be forced pushed a bit so it will be likely wasted.
I think I did a faithful job of translating the tests. A bit of review here would be helpful.
I do think it would be good to merge this PR soon into the v1 branch so we have something to work off once unfinished work is done.
Checking out the branch and poke around and give feedback would be the most helpful thing.
Run the (sort of) working example:
Checklists
All Submissions:
cargo fmt
andcargo clippy
before committingBugfixes: