/// Construct from an iterator of block data.
///
+ /// # Returns
+ ///
+ /// Returns the checkpoint chain tip on success.
+ ///
+ /// # Errors
+ ///
/// Returns `Err(None)` if `blocks` doesn't yield any data. If the blocks are not in ascending
- /// height order, or there are any `prev_blockhash` mismatches, then returns an `Err(..)`
- /// containing the last checkpoint that would have been extended.
+ /// height order, or there are any `prev_blockhash` mismatches, then returns `Err(Some(..))`
+ /// containing the last checkpoint that was successfully extended.
pub fn from_blocks(blocks: impl IntoIterator<Item = (u32, D)>) -> Result<Self, Option<Self>> {
let mut blocks = blocks.into_iter();
let (height, data) = blocks.next().ok_or(None)?;
result.unwrap_err().eq_ptr(&cp),
"should return self on error"
);
+
+ // Verify the original checkpoint at 100 is still intact
+ assert_eq!(cp.height(), 100);
+ assert_eq!(cp.hash(), hash!("block_100"));
}
/// Test that push succeeds when prev_blockhash matches self's hash for contiguous height.
let new_cp = result.unwrap();
assert_eq!(new_cp.height(), 101);
assert_eq!(new_cp.hash(), hash!("block_101"));
+ assert_eq!(
+ new_cp.iter().count(),
+ 2,
+ "should have 2 checkpoints (100, 101)"
+ );
}
/// Test that push creates a placeholder for non-contiguous heights with prev_blockhash.