@@ -207,46 +207,6 @@ impl CheckPoint {
207
207
base. extend ( core:: iter:: once ( block_id) . chain ( tail. into_iter ( ) . rev ( ) ) )
208
208
. expect ( "tail is in order" )
209
209
}
210
-
211
- /// Apply `changeset` to the checkpoint.
212
- fn apply_changeset ( mut self , changeset : & ChangeSet ) -> Result < CheckPoint , MissingGenesisError > {
213
- if let Some ( start_height) = changeset. blocks . keys ( ) . next ( ) . cloned ( ) {
214
- // changes after point of agreement
215
- let mut extension = BTreeMap :: default ( ) ;
216
- // point of agreement
217
- let mut base: Option < CheckPoint > = None ;
218
-
219
- for cp in self . iter ( ) {
220
- if cp. height ( ) >= start_height {
221
- extension. insert ( cp. height ( ) , cp. hash ( ) ) ;
222
- } else {
223
- base = Some ( cp) ;
224
- break ;
225
- }
226
- }
227
-
228
- for ( & height, & hash) in & changeset. blocks {
229
- match hash {
230
- Some ( hash) => {
231
- extension. insert ( height, hash) ;
232
- }
233
- None => {
234
- extension. remove ( & height) ;
235
- }
236
- } ;
237
- }
238
-
239
- let new_tip = match base {
240
- Some ( base) => base
241
- . extend ( extension. into_iter ( ) . map ( BlockId :: from) )
242
- . expect ( "extension is strictly greater than base" ) ,
243
- None => LocalChain :: from_blocks ( extension) ?. tip ( ) ,
244
- } ;
245
- self = new_tip;
246
- }
247
-
248
- Ok ( self )
249
- }
250
210
}
251
211
252
212
/// Iterates over checkpoints backwards.
@@ -275,6 +235,49 @@ impl IntoIterator for CheckPoint {
275
235
}
276
236
}
277
237
238
+ /// Apply `changeset` to the checkpoint.
239
+ fn apply_changeset_to_checkpoint (
240
+ mut init_cp : CheckPoint ,
241
+ changeset : & ChangeSet ,
242
+ ) -> Result < CheckPoint , MissingGenesisError > {
243
+ if let Some ( start_height) = changeset. blocks . keys ( ) . next ( ) . cloned ( ) {
244
+ // changes after point of agreement
245
+ let mut extension = BTreeMap :: default ( ) ;
246
+ // point of agreement
247
+ let mut base: Option < CheckPoint > = None ;
248
+
249
+ for cp in init_cp. iter ( ) {
250
+ if cp. height ( ) >= start_height {
251
+ extension. insert ( cp. height ( ) , cp. hash ( ) ) ;
252
+ } else {
253
+ base = Some ( cp) ;
254
+ break ;
255
+ }
256
+ }
257
+
258
+ for ( & height, & hash) in & changeset. blocks {
259
+ match hash {
260
+ Some ( hash) => {
261
+ extension. insert ( height, hash) ;
262
+ }
263
+ None => {
264
+ extension. remove ( & height) ;
265
+ }
266
+ } ;
267
+ }
268
+
269
+ let new_tip = match base {
270
+ Some ( base) => base
271
+ . extend ( extension. into_iter ( ) . map ( BlockId :: from) )
272
+ . expect ( "extension is strictly greater than base" ) ,
273
+ None => LocalChain :: from_blocks ( extension) ?. tip ( ) ,
274
+ } ;
275
+ init_cp = new_tip;
276
+ }
277
+
278
+ Ok ( init_cp)
279
+ }
280
+
278
281
/// This is a local implementation of [`ChainOracle`].
279
282
#[ derive( Debug , Clone , PartialEq ) ]
280
283
pub struct LocalChain {
@@ -490,7 +493,7 @@ impl LocalChain {
490
493
/// Apply the given `changeset`.
491
494
pub fn apply_changeset ( & mut self , changeset : & ChangeSet ) -> Result < ( ) , MissingGenesisError > {
492
495
let old_tip = self . tip . clone ( ) ;
493
- let new_tip = old_tip . apply_changeset ( changeset) ?;
496
+ let new_tip = apply_changeset_to_checkpoint ( old_tip , changeset) ?;
494
497
self . tip = new_tip;
495
498
debug_assert ! ( self . _check_changeset_is_applied( changeset) ) ;
496
499
Ok ( ( ) )
@@ -848,12 +851,10 @@ fn merge_chains(
848
851
if is_update_height_superset_of_original {
849
852
return Ok ( ( update_tip, changeset) ) ;
850
853
} else {
851
- let new_tip =
852
- original_tip. apply_changeset ( & changeset) . map_err ( |_| {
853
- CannotConnectError {
854
- try_include_height : 0 ,
855
- }
856
- } ) ?;
854
+ let new_tip = apply_changeset_to_checkpoint ( original_tip, & changeset)
855
+ . map_err ( |_| CannotConnectError {
856
+ try_include_height : 0 ,
857
+ } ) ?;
857
858
return Ok ( ( new_tip, changeset) ) ;
858
859
}
859
860
}
@@ -889,10 +890,10 @@ fn merge_chains(
889
890
}
890
891
}
891
892
892
- let new_tip = original_tip
893
- . apply_changeset ( & changeset)
894
- . map_err ( |_| CannotConnectError {
893
+ let new_tip = apply_changeset_to_checkpoint ( original_tip, & changeset) . map_err ( |_| {
894
+ CannotConnectError {
895
895
try_include_height : 0 ,
896
- } ) ?;
896
+ }
897
+ } ) ?;
897
898
Ok ( ( new_tip, changeset) )
898
899
}
0 commit comments