@@ -23,24 +23,6 @@ struct CPInner {
2323 prev : Option < Arc < CPInner > > ,
2424}
2525
26- /// Occurs when the caller contructs a [`CheckPoint`] with a height that is not higher than the
27- /// previous checkpoint it points to.
28- #[ derive( Debug , Clone , PartialEq ) ]
29- pub struct NewCheckPointError {
30- /// The height of the new checkpoint.
31- pub new_height : u32 ,
32- /// The height of the previous checkpoint.
33- pub prev_height : u32 ,
34- }
35-
36- impl core:: fmt:: Display for NewCheckPointError {
37- fn fmt ( & self , f : & mut core:: fmt:: Formatter < ' _ > ) -> core:: fmt:: Result {
38- write ! ( f, "cannot construct checkpoint with a height ({}) that is not higher than the previous checkpoint ({})" , self . new_height, self . prev_height)
39- }
40- }
41-
42- impl std:: error:: Error for NewCheckPointError { }
43-
4426impl CheckPoint {
4527 /// Construct a [`CheckPoint`] from a [`BlockId`].
4628 pub fn new ( block : BlockId ) -> Self {
@@ -248,27 +230,30 @@ impl LocalChain {
248230 pub fn update ( & mut self , new_tip : CheckPoint ) -> Result < ChangeSet , CannotConnectError > {
249231 let mut updated_cps = BTreeMap :: < u32 , CheckPoint > :: new ( ) ;
250232 let mut agreement_height = Option :: < u32 > :: None ;
251- let mut complete_match = false ;
233+ let mut agreement_ptr_matches = false ;
252234
253235 for cp in new_tip. iter ( ) {
254236 let block = cp. block_id ( ) ;
255- let original_cp = self . checkpoints . get ( & block. height ) ;
256237
257- // if original block of height does not exist, or if the hash does not match we will
258- // need to update the original checkpoint at that height
259- if original_cp. map ( CheckPoint :: block_id) != Some ( block) {
260- updated_cps. insert ( block. height , cp. clone ( ) ) ;
261- }
238+ match self . checkpoints . get ( & block. height ) {
239+ Some ( original_cp) if original_cp. block_id ( ) == block => {
240+ let ptr_matches = Arc :: as_ptr ( & original_cp. 0 ) == Arc :: as_ptr ( & cp. 0 ) ;
241+
242+ // only record the first agreement height
243+ if agreement_height. is_none ( ) && original_cp. block_id ( ) == block {
244+ agreement_height = Some ( block. height ) ;
245+ agreement_ptr_matches = ptr_matches;
246+ }
262247
263- if let Some ( original_cp ) = original_cp {
264- // record the first agreement height
265- if agreement_height . is_none ( ) && original_cp . block_id ( ) == block {
266- agreement_height = Some ( block . height ) ;
248+ // break if the internal pointers of the checkpoints are the same
249+ if ptr_matches {
250+ break ;
251+ }
267252 }
268- // break if the internal pointers of the checkpoints are the same
269- if Arc :: as_ptr ( & original_cp . 0 ) == Arc :: as_ptr ( & cp . 0 ) {
270- complete_match = true ;
271- break ;
253+ // only insert into `updated_cps` if cp is actually updated (original cp is `None`,
254+ // or block ids do not match)
255+ _ => {
256+ updated_cps . insert ( block . height , cp . clone ( ) ) ;
272257 }
273258 }
274259 }
@@ -315,7 +300,11 @@ impl LocalChain {
315300 if let Some ( & start_height) = updated_cps. keys ( ) . next ( ) {
316301 self . checkpoints . split_off ( & invalidate_lb) ;
317302 self . checkpoints . append ( & mut updated_cps) ;
318- if !self . is_empty ( ) && !complete_match {
303+
304+ // we never need to fix links if either:
305+ // 1. the original chain is empty
306+ // 2. the pointers match at the first point of agreement (where the block ids are equal)
307+ if !( self . is_empty ( ) || agreement_ptr_matches) {
319308 self . fix_links ( start_height) ;
320309 }
321310 }
0 commit comments