-
Notifications
You must be signed in to change notification settings - Fork 404
refactor!: Implement generics for CheckPoint
, LocalChain
, and spk_client
types
#1582
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
base: master
Are you sure you want to change the base?
Conversation
CheckPoint
takes a genericCheckPoint
and LocalChain
a899049
to
7c13781
Compare
7c13781
to
d934a6c
Compare
ea1cf8b
to
bf90ea5
Compare
c278804
to
6300d7c
Compare
CheckPoint
and LocalChain
CheckPoint
, LocalChain
, and spk_client
types
6300d7c
to
315f687
Compare
Tests are passing for me. But I think we should still have the function diff--- a/crates/chain/src/local_chain.rs
+++ b/crates/chain/src/local_chain.rs
@@ -270,8 +270,9 @@ where
};
let (mut chain, _) = Self::from_genesis(genesis_data);
chain.apply_changeset(&changeset)?;
+ debug_assert!(chain._check_changeset_is_applied(&changeset));
Ok(chain)
}
/// Construct a [`LocalChain`] from a given `checkpoint` tip.
@@ -303,16 +304,18 @@ where
update: CheckPoint<D>,
) -> Result<ChangeSet<D>, CannotConnectError> {
let (new_tip, changeset) = merge_chains(self.tip.clone(), update)?;
self.tip = new_tip;
+ debug_assert!(self._check_changeset_is_applied(&changeset));
Ok(changeset)
}
/// Apply the given `changeset`.
pub fn apply_changeset(&mut self, changeset: &ChangeSet<D>) -> Result<(), MissingGenesisError> {
let old_tip = self.tip.clone();
let new_tip = apply_changeset_to_checkpoint(old_tip, changeset)?;
self.tip = new_tip;
+ debug_assert!(self._check_changeset_is_applied(changeset));
Ok(())
}
/// Derives an initial [`ChangeSet`], meaning that it can be applied to an empty chain to
@@ -401,8 +404,30 @@ where
None => return Ok(ChangeSet::default()),
};
Ok(changeset)
}
+
+ fn _check_changeset_is_applied(&self, changeset: &ChangeSet<D>) -> bool {
+ let mut cur = self.tip.clone();
+ for (&exp_height, exp_data) in changeset.blocks.iter().rev() {
+ match cur.get(exp_height) {
+ Some(cp) => {
+ if cp.height() != exp_height
+ || Some(cp.hash()) != exp_data.map(|d| d.to_blockhash())
+ {
+ return false;
+ }
+ cur = cp;
+ }
+ None => {
+ if exp_data.is_some() {
+ return false;
+ }
+ }
+ }
+ }
+ true
+ }
}
|
b5d4872
to
e1e1959
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 e1e1959
e1e1959
to
ac0cd4f
Compare
58a5566
to
dabb869
Compare
ACK dabb869 |
9aef131
to
fed0c50
Compare
8906806
to
0a39fa7
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 0a39fa7 pending a CI fix.
I left comments mostly for discussion. Also there was a comment #1582 (review) suggesting to use B
instead of D
. I don't have much preference though.
I haven't done a deep review but I support merging this now that we're done with the |
0a39fa7
to
d4bd7e5
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.
utACK d4bd7e5
The code looks good to me, I only left a minor question and nit. I didn't test it on a complicated example yet.
ACK 4dce5ad |
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.
utACK 4dce5ad
I also re-read through the whole history and this one has certainly been a journey so thanks to @LagginTimes and all the reviewers for sticking with it.
I look forward to the followup PRs to integrate chain client specific data in the checkpoints. I expect custom data will break existing persistence so being able to persist the data in a generic way and having a good persistence test suite such as #2012 will be handy.
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 4dce5ad
Looking back through the codebase, I noticed that we've introduced a condition that wasn't there before, and I’m wondering about the best way to handle it. Since a One idea is to modify pub trait ToBlockHash {
/* OTHER METHODS */
/// Returns `None` if the type has no knowledge of the previous blockhash.
fn prev_blockhash(&self) -> Option<BlockHash>;
} Then we need to modify
|
Implements #1937.
Description
This PR is a step towards header checkpointing for
bdk_electrum
. The goal is to be able to store whole headers inCheckPoint
so they do not have to be re-downloaded. Storing headers this way would be a prerequisite for caching of merkle proofs and for median time passed.Notes to the reviewers
Changelog notice
CheckPoint
takes in a generic.LocalChain
andChangeSet
take in generics.spk_client
types can take in generics.Checklists
All Submissions:
cargo fmt
andcargo clippy
before committing