-
Notifications
You must be signed in to change notification settings - Fork 389
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
765d584
to
7488001
Compare
7488001
to
d22c61f
Compare
+1 for this feature, |
At a high level I think the API would be cleaner if the generic methods had the simpler names (new, push, extend, insert) and the old methods were renamed
fn data_ref(&self) -> &B {}
fn data(&self) -> B where B: Clone {} // or Copy
Remaining questions:
Edit: I added my review with some API suggestions in LagginTimes#5 |
d22c61f
to
5acf81b
Compare
5acf81b
to
4148e29
Compare
@LagginTimes is this ready to review again? Remember to mark it as so and request reviewers, otherwise no one will know about it. |
4148e29
to
3d7f48c
Compare
3d7f48c
to
69d8643
Compare
What was the discussion around breaking changes? Were we okay to break the API? |
CheckPoint
, LocalChain
, and spk_client
typesCheckPoint
, LocalChain
, and spk_client
types
Iirc the consensus was for this to be a breaking change to be a cleaner API. |
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.
Thanks for pushing this forward.
Please double check (brownie points for triple check) over all the methods of a struct to see whether they are coherent, whether any more methods can be made generic and whether the method names and generic parameter names are coherent and make sense.
Let's make all generic parameter names for block data be consistent across the board. I'm in favor of B
.
pub struct LocalChain { | ||
tip: CheckPoint, | ||
#[derive(Debug, Clone)] | ||
pub struct LocalChain<H = BlockHash> { |
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 would use B
(as in block) or D
(as in data) for the type generic instead of H
(which I'm assuming stands for header, but we aren't necessarily using headers here).
self.tip.get(0).expect("genesis must exist").hash() | ||
} | ||
|
||
impl LocalChain<BlockHash> { | ||
/// Construct [`LocalChain`] from genesis `hash`. | ||
#[must_use] | ||
pub fn from_genesis_hash(hash: BlockHash) -> (Self, 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.
I would remove this and have from_genesis(data: B)
instead which would work with all types.
self.tip.get(0).expect("genesis must exist").hash() | ||
} | ||
|
||
impl LocalChain<BlockHash> { |
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.
Let's make these following methods generic for all H
s.
impl LocalChain<D> {
pub fn from_genesis(data: D) -> (Self, ChangeSet<D>);
pub fn from_changeset(changeset: ChangeSet<D>) -> Result<Self>;
pub fn from_blocks(blocks: BTreeMap<u32, D>) -> Result<Self>;
pub fn apply_update(&mut self, update: CheckPoint<D>) -> Result<ChangeSet>;
pub fn apply_blockhash_changeset( | ||
&mut self, | ||
changeset: &ChangeSet, | ||
) -> Result<(), MissingGenesisError> { | ||
self.apply_changeset(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.
This doesn't look helpful as .apply_changeset
does the exact same thing.
@@ -279,29 +258,7 @@ impl LocalChain { | |||
/// | |||
/// Replacing the block hash of an existing checkpoint will result in an error. | |||
pub fn insert_block(&mut self, block_id: BlockId) -> Result<ChangeSet, AlterCheckPointError> { |
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.
This method is no longer useful as .insert_data
does the same thing. Just rename .insert_data
to .insert_block
.
pub fn from_block_ids( | ||
block_ids: impl IntoIterator<Item = BlockId>, | ||
) -> Result<Self, Option<Self>> { |
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.
Let's rework this method to be generic over D
:
pub fn from_block_ids( | |
block_ids: impl IntoIterator<Item = BlockId>, | |
) -> Result<Self, Option<Self>> { | |
pub fn from_blocks( | |
blocks: impl IntoIterator<Item = (u32, D)>, | |
) -> Result<Self, Option<Self>> { |
pub fn extend_block_ids( | ||
self, | ||
blockdata: impl IntoIterator<Item = BlockId>, | ||
) -> Result<Self, Self> { | ||
self.extend( | ||
blockdata | ||
.into_iter() | ||
.map(|block| (block.height, block.hash)), | ||
) | ||
} | ||
|
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.
Let's remove this as extend
does the same thing.
pub fn insert_block_id(self, block_id: BlockId) -> Self { | ||
self.insert(block_id.height, block_id.hash) | ||
} |
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.
Remove.
pub fn push_block_id(self, block: BlockId) -> Result<Self, Self> { | ||
self.push(block.height, block.hash) | ||
} |
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.
Remove.
@@ -387,14 +388,14 @@ impl<I> SyncRequest<I> { | |||
/// See also [`SyncRequest`]. | |||
#[must_use] | |||
#[derive(Debug)] | |||
pub struct SyncResponse<A = ConfirmationBlockTime> { | |||
pub struct SyncResponse<B = BlockHash, A = ConfirmationBlockTime> { |
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 know this is a breaking change, but introducing a generic parameter before one that already exists can be really annoying. Introduce it at the end please.
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.TODO:
CheckPoint
to take in a generic.LocalChange
to take in a generic.spk_client
types to take in generics.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