Skip to content
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

Implement persistence with the new structures #965

Merged
merged 2 commits into from
May 10, 2023

Conversation

evanlinjin
Copy link
Member

@evanlinjin evanlinjin commented May 4, 2023

Description

This is part of #895 and #971

  • Introduce a more generic version of the keychain::persist::* structures that only needs a single generic for the changeset type.

Additional changes:

  • The Append trait has a new method is_empty.
  • Introduce Store structure for bdk_file_store (which implements PersistBackend).

Changelog notice

Checklists

All Submissions:

  • I've signed all my commits
  • I followed the contribution guidelines
  • 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

@notmandatory notmandatory added this to the 1.0.0-alpha.1 milestone May 4, 2023
@evanlinjin evanlinjin force-pushed the persist_redesign branch 3 times, most recently from 46259f5 to f8dd5e2 Compare May 9, 2023 04:38
@evanlinjin evanlinjin marked this pull request as ready for review May 9, 2023 04:48
This is a more generic version of `keychain::persist::*` structures.

Additional changes:

* The `Append` trait has a new method `is_empty`.
* Introduce `Store` structure for `bdk_file_store`.
@evanlinjin evanlinjin requested a review from LLFourn May 9, 2023 05:01
Copy link
Contributor

@LLFourn LLFourn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a few nits. Otherwise LGTM.

crates/file_store/src/store.rs Show resolved Hide resolved
crates/file_store/src/store.rs Outdated Show resolved Hide resolved
crates/file_store/src/entry_iter.rs Show resolved Hide resolved
crates/file_store/src/store.rs Outdated Show resolved Hide resolved
crates/file_store/src/store.rs Outdated Show resolved Hide resolved
@@ -64,20 +64,35 @@ impl<A: Anchor> Anchor for &'static A {
pub trait Append {
/// Append another object of the same type onto `self`.
fn append(&mut self, other: Self);

/// Returns whether the structure is considered empty.
fn is_empty(&self) -> bool;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's say I wanted to implement Append for a u32 to represent a monotonically increasing value -- I guess u32::MIN would return true for is_empty.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think implementing Append for u32 is a rather confusing combination. Option<u32> or using a wrapped type makes more sense for me.

@evanlinjin evanlinjin merged commit 05d353c into bitcoindevkit:master May 10, 2023
#[derive(Debug)]
pub struct Persist<B, C> {
backend: B,
stage: C,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe it should be S for stage, instead of C?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

C for changeset though 😮

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then do changeset: C :P

Copy link
Member

@notmandatory notmandatory May 23, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I support changeset: C 🙂

Comment on lines +46 to +48
let mut temp = C::default();
core::mem::swap(&mut temp, &mut self.stage);
self.backend.write_changes(&temp)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mhhhh maybe put a small comment here, it took me a second to figure out what you were trying to do (commit changes and clean self.stage at the same time)

Also, a shorter way of writing this, but not necessarily a cleaner one, might be:

self.backend.write_changes(core::mem::take(&mut self.stage))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually shouldn't we only clear it in the case that it succeeds.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good point

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

    /// Commit the staged changes to the underlying persistance backend.
    ///
    /// Changes that are committed (if any) are returned.
    ///
    /// # Error
    ///
    /// Returns a backend-defined error if this fails.
    pub fn commit(&mut self) -> Result<Option<C>, B::WriteError> {
        if self.stage.is_empty() {
            return Ok(None);
        }
        self.backend
            .write_changes(&self.stage)
            // if written successfully, take and return `self.stage`
            .map(|_| Some(core::mem::take(&mut self.stage)))
    }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

db_file: Option<&'t mut File>,

/// The file position for the first read of `db_file`.
start_pos: Option<u64>,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: maybe expand in the docs why it's an Option and what happens when this is None

@notmandatory notmandatory mentioned this pull request Jul 4, 2023
24 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

5 participants