bdk v1.0.0-alpha.0#793
Conversation
bf2ba37 to
cbe573e
Compare
afilini
left a comment
There was a problem hiding this comment.
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.
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.
"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.
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.
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) { |
danielabrozzoni
left a comment
There was a problem hiding this comment.
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.
Could you expand a bit on why is Reset being removed?
There was a problem hiding this comment.
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.
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.
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.
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.
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.
This reminds me: the 1.0 release is a good opportunity to rename LocalUtxo to LocalTxOut :)
There was a problem hiding this comment.
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.
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
notmandatory
left a comment
There was a problem hiding this comment.
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
danielabrozzoni
left a comment
There was a problem hiding this comment.
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-featuresnow.esploraAPIs changed
syncmethod. This is replaced withapply_wallet_scan.ensure_derived_up_towhich sets your derivation to at least the argument. Unlikeensure_addresses_cachedused to do this will alter what getting a new address gives you.AddressIndex::Resetis 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_unusedwhich 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_corewe 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 fmtandcargo clippybefore committingBugfixes: