@@ -11,11 +11,22 @@ pub use bdk_core::{CheckPoint, CheckPointIter};
1111use bitcoin:: block:: Header ;
1212use bitcoin:: BlockHash ;
1313
14+ /// Error for `apply_changeset_to_checkpoint`.
15+ #[ derive( Debug ) ]
16+ struct ApplyChangeSetError < D > {
17+ error : Option < CheckPoint < D > > ,
18+ }
19+
1420/// Apply `changeset` to the checkpoint.
21+ ///
22+ /// # Errors
23+ ///
24+ /// - If constructing the new chain from the provided `changeset` fails, then a
25+ /// [`ApplyChangeSetError`] is returned.
1526fn apply_changeset_to_checkpoint < D > (
1627 mut init_cp : CheckPoint < D > ,
1728 changeset : & ChangeSet < D > ,
18- ) -> Result < CheckPoint < D > , MissingGenesisError >
29+ ) -> Result < CheckPoint < D > , ApplyChangeSetError < D > >
1930where
2031 D : ToBlockHash + fmt:: Debug + Copy ,
2132{
4859 let new_tip = match base {
4960 Some ( base) => base
5061 . extend ( extension)
51- . expect ( "extension is strictly greater than base" ) ,
52- None => LocalChain :: from_blocks ( extension) ?. tip ( ) ,
62+ . map_err ( Option :: Some )
63+ . map_err ( |error| ApplyChangeSetError { error } ) ?,
64+ None => LocalChain :: from_blocks ( extension)
65+ . map_err ( |error| ApplyChangeSetError { error } ) ?
66+ . tip ( ) ,
5367 } ;
5468 init_cp = new_tip;
5569 }
@@ -251,13 +265,16 @@ where
251265 ///
252266 /// The [`BTreeMap`] enforces the height order. However, the caller must ensure the blocks are
253267 /// all of the same chain.
254- pub fn from_blocks ( blocks : BTreeMap < u32 , D > ) -> Result < Self , MissingGenesisError > {
268+ ///
269+ /// Returns `Err(None)` if `blocks` doesn't contain a value at height `0` a.k.a
270+ /// "genesis" block.
271+ pub fn from_blocks ( blocks : BTreeMap < u32 , D > ) -> Result < Self , Option < CheckPoint < D > > > {
255272 if !blocks. contains_key ( & 0 ) {
256- return Err ( MissingGenesisError ) ;
273+ return Err ( None ) ;
257274 }
258275
259276 Ok ( Self {
260- tip : CheckPoint :: from_blocks ( blocks) . expect ( "blocks must be in order" ) ,
277+ tip : CheckPoint :: from_blocks ( blocks) ? ,
261278 } )
262279 }
263280
@@ -312,7 +329,8 @@ where
312329 /// Apply the given `changeset`.
313330 pub fn apply_changeset ( & mut self , changeset : & ChangeSet < D > ) -> Result < ( ) , MissingGenesisError > {
314331 let old_tip = self . tip . clone ( ) ;
315- let new_tip = apply_changeset_to_checkpoint ( old_tip, changeset) ?;
332+ let new_tip =
333+ apply_changeset_to_checkpoint ( old_tip, changeset) . map_err ( |_| MissingGenesisError ) ?;
316334 self . tip = new_tip;
317335 debug_assert ! ( self . _check_changeset_is_applied( changeset) ) ;
318336 Ok ( ( ) )
@@ -702,9 +720,9 @@ where
702720 }
703721
704722 // Apply changeset to tip.
705- let new_tip = apply_changeset_to_checkpoint ( self . tip ( ) , & changeset) . map_err ( |_ | {
723+ let new_tip = apply_changeset_to_checkpoint ( self . tip ( ) , & changeset) . map_err ( |e | {
706724 CannotConnectError {
707- try_include_height : 0 ,
725+ try_include_height : e . error . as_ref ( ) . map_or ( 0 , CheckPoint :: height ) ,
708726 }
709727 } ) ?;
710728
0 commit comments