-
Notifications
You must be signed in to change notification settings - Fork 412
Refactor file store #1684
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 file store #1684
Conversation
ValuedMammal
left a comment
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 did a first pass. Overall it looks good. I also made suggestions in this commit ValuedMammal/bdk@6312ca3
If you plan to rebase make sure commits compile on their own. For example changing a method name and updating the method call sites should be in the same commit in my opinion.
|
@ValuedMammal thanks for the review, I'm already working in the changes. |
1251b82 to
5a7fe42
Compare
|
Rebased on 03a08bb |
|
In 0f104cc: error[E0432]: unresolved import `crate::FileError`
--> crates/file_store/src/store.rs:1:41
|
1 | use crate::{bincode_options, EntryIter, FileError, IterError};
| ^^^^^^^^^ no `FileError` in the root
For more information about this error, try `rustc --explain E0432`.
error: could not compile `bdk_file_store` (lib) due to 1 previous errorMaybe just squash in the next commit 8897a20 but keep the commit message from 8897a20 ? |
5a7fe42 to
3b695ce
Compare
Thanks! should be fixed now. I checked each commit with: git rebase --exec 'cargo build; cargo test; cargo clippy; cargo fmt' 0f104c^ |
ValuedMammal
left a comment
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 18aa75e I tested on example_esplora
|
@notmandatory we have been trying to figure out with @ValuedMammal what would be the correct handling for this change. This semver FAQ entry implies it isn't a breaking change for wallet as long as we don't change the API, but this single line is a breaking change, so I think if we don't rollback the error name to the previous one, we should wait until What do you think we should do? |
|
I tried to just change the name of So I decided to go with the option to use |
eed9e20 to
7d5f5dd
Compare
evanlinjin
left a comment
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 like where this is going.
crates/file_store/src/store.rs
Outdated
| } | ||
|
|
||
| /// Attempt to open existing [`Store`] file; create it if the file is non-existent. | ||
| /// Aggregate [`Store`] changesets and return them as a single changeset. |
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.
| /// Aggregate [`Store`] changesets and return them as a single changeset. | |
| /// Dump the aggregate of all changesets in [`Store`]. |
7d5f5dd to
ea151dd
Compare
`Path.exists` is not safe against time-of-creation, time-of-use (TOCTOU) bugs. `OpenOptions.create_new` on the other hand is atomic, so not prone to this kind of problems.
The changes in this commit were motivated due to a bug in the `StoreFile` which caused old data to be lost if the file was `open` instead of created and new data was appended. The bugfix later motivated a general name cleanup in StoreFile's methods and errors and some minor changes in their signatures. FileError was renamed to StoreError, which now includes the IterError variants, allowing the remplacement of the former form. The new StoreFile methods are: - create: create file in write only mode or fail if file exists. - load: open existing file, check integrity of content and retrieve Store. - append: add new changesets to Store. Do nothing if changeset is empty. - dump: aggregate and retrieve all stored changesets in store. - load_or_create: load if file exists, create if not, and retrieve Store.
ea151dd to
52f2061
Compare
|
Rebased onto 362c3dc |
evanlinjin
left a comment
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 54251a7
e125014 feat(examples): Change `example_wallet_rpc` to detect evictions. (志宇) 12b00e0 feat(wallet): Add method `apply_evicted_txs` (valued mammal) a247215 deps!: update bdk_chain to 0.22.0 (valued mammal) f882945 ci: Unpin some dependencies (valued mammal) Pull request description: This PR updates `bdk_chain` dependency to the latest version 0.22.0 ### Notes to the reviewers This PR doesn't make use of `CanonicalizationParams` for any advanced use cases - instead we rely on the default params for all tx-graph queries. fixes #202 fixes #224 ### Changelog notice - deps: bump `bdk_chain` to 0.22.0 - deps: bump `bdk_file_store` to 0.20.0 #### Added - Added `start_sync_with_revealed_spks_at` - Added `start_full_scan_at` - Added `apply_evicted_txs` #### Changed - `start_sync_with_revealed_spks` is feature gated by "std", as it uses the system time to provide the time of the sync and also the tx last-seen. - `apply_update` no longer requires std, as the timestamp is provided in the sync / full scan request - `start_full_scan` is also gated behind "std" - `start_sync_*` now includes the expected SPK history (via `list_expected_spk_txids`) #### Removed - Removed `apply_update_at` #### BREAKING - `bdk_core::TxUpdate` is non-exhaustive bitcoindevkit/bdk#1838 - For the optional file_store feature, the Load variant of the `FileStoreError` is changed to hold a new inner type bitcoindevkit/bdk#1684 #### Changes to persisted data The `tx_graph::ChangeSet` gained a new default-able field `last_evicted` to persist the fact that a tx is no longer part of the canonical chain. ### 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 * [x] I've added docs for the new feature * [x] This pull request breaks the existng API * [x] I'm linking the issue being fixed by this PR ACKs for top commit: notmandatory: ACK e125014 Tree-SHA512: 91f77e4268aac0aaee2503a3fdca13754fc291159b9f37b0997be8c011b02b8ac16b4b6a7edbbb731005c83b37d438666fb803dbe18a6b9496b11f7e3e1ab155
Description
The
Store::openmethod doesn't recovers the previousStorestate saved in the file and emplaces the file pointer just after the magic bytes prefix, this later is agravated byStore::append_changesetwhich sets the file pointer after the last written changeset. The combination of both causes the lost of any previous changeset there may have been in the file.Is natural to think this shouldn't be the expected behavior, as @KnowWhoami pointed out in #1517, and the
Storeshould recover the previous changesets stored in the file store.The approach proposed in #1632 triggered a discussion about more changes in
Store, which motivated the current refactor.Besides the fix for #1517, the following methods have been changed/renamed/repurposed in Store:
create: create file and retrieve store, if exists fail.load: load changesets from file, aggregate them and return aggregated changeset andStore. If there are problems with decoding, fail.dump: aggregate all changesets and return them.load_or_create: try load or fallback to create.Fixes #1517.
Overrides #1632.
Notes to the reviewers
Load return type is
Result<(Option<C>, Store), StoreErrorWithDump>to allow methods which doesn't useWalletPersisterto get the aggregated changeset right away.Dump is kept to allow
WalletPersister::initializemethod to retrieve the aggregated changeset without forcing the inclusion of the additional parameters needed bystore::loadto the trait, which would also affect therusqliteimplementation.Changelog notice
Added:
StoreErrorenum, which includesIo,BincodeandInvalidMagicBytes.READMEforfile store.Changed:
Store::create_newtoStore::create, with new return type:Result<Self, StoreError>Store::opentoStore::load, with new return type:Result<(Self, Option<C>), StoreErrorWithDump<C>>Store::open_or_createtoStore::load_or_create, with new return type:Result<(Option<C>, Self), StoreErrorWithDump<C>>Store::aggregate_changesetstoStore::dump, with new return type:Result<Option<C>, StoreErrorWithDump<C>>FileErrortoStoreErrorAggregateChangesetsErrortoStoreErrorWithDump, which now can include all the variants ofStoreErrorin the error field.Deleted:
IterErrordeleted.Checklists
All Submissions:
I've signed all my commitsI followed the contribution guidelinesI rancargo fmtandcargo clippybefore committingNew Features:
I've added tests for the new featureI've added docs for the new featureBugfixes:
This pull request breaks the existing APII've added tests to reproduce the issue which are now passingI'm linking the issue being fixed by this PR