-
Notifications
You must be signed in to change notification settings - Fork 329
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
base: master
Are you sure you want to change the base?
Refactor file store #1684
Conversation
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. |
`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.
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 error Maybe just squash in the next commit 8897a20 but keep the commit message from 8897a20 ? |
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.
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^ |
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
Description
The
Store::open
method doesn't recovers the previousStore
state saved in the file and emplaces the file pointer just after the magic bytes prefix, this later is agravated byStore::append_changeset
which 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
Store
should 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 useWalletPersister
to get the aggregated changeset right away.Dump is kept to allow
WalletPersister::initialize
method to retrieve the aggregated changeset without forcing the inclusion of the additional parameters needed bystore::load
to the trait, which would also affect therusqlite
implementation.Changelog notice
Added:
StoreError
enum, which includesIo
,Bincode
andInvalidMagicBytes
.README
forfile store
.Changed:
Store::create_new
toStore::create
, with new return type:Result<Self, StoreError>
Store::open
toStore::load
, with new return type:Result<(Option<C>, Self), StoreErrorWithDump<C>>
Store::open_or_create
toStore::load_or_create
, with new return type:Result<(Option<C>, Self), StoreErrorWithDump<C>>
Store::aggregate_changesets
toStore::dump
, with new return type:Result<Option<C>, StoreErrorWithDump<C>>
FileError
toStoreError
AggregateChangesetsError
toStoreErrorWithDump
, which now can include all the variants ofStoreError
in the error field.Deleted:
IterError
deleted.Checklists
All Submissions:
I've signed all my commitsI followed the contribution guidelinesI rancargo fmt
andcargo clippy
before 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