@@ -111,7 +111,7 @@ use sp_api::{ApiExt, ProvideRuntimeApi};
111
111
use sp_application_crypto:: AppKey ;
112
112
use sp_block_builder:: BlockBuilder as BlockBuilderApi ;
113
113
use sp_blockchain:: {
114
- Backend as _, Error as ClientError , ForkBackend , HeaderBackend , HeaderMetadata ,
114
+ Backend as _, BlockStatus , Error as ClientError , ForkBackend , HeaderBackend , HeaderMetadata ,
115
115
Result as ClientResult ,
116
116
} ;
117
117
use sp_consensus:: {
@@ -1133,11 +1133,17 @@ where
1133
1133
let hash = block. header . hash ( ) ;
1134
1134
let parent_hash = * block. header . parent_hash ( ) ;
1135
1135
1136
- if block. with_state ( ) {
1137
- // When importing whole state we don't calculate epoch descriptor, but rather
1138
- // read it from the state after import. We also skip all verifications
1139
- // because there's no parent state and we trust the sync module to verify
1140
- // that the state is correct and finalized.
1136
+ let info = self . client . info ( ) ;
1137
+ let number = * block. header . number ( ) ;
1138
+
1139
+ if info. block_gap . map_or ( false , |( s, e) | s <= number && number <= e) || block. with_state ( ) {
1140
+ // Verification for imported blocks is skipped in two cases:
1141
+ // 1. When importing blocks below the last finalized block during network initial
1142
+ // synchronization.
1143
+ // 2. When importing whole state we don't calculate epoch descriptor, but rather
1144
+ // read it from the state after import. We also skip all verifications
1145
+ // because there's no parent state and we trust the sync module to verify
1146
+ // that the state is correct and finalized.
1141
1147
return Ok ( ( block, Default :: default ( ) ) )
1142
1148
}
1143
1149
@@ -1399,18 +1405,24 @@ where
1399
1405
) -> Result < ImportResult , Self :: Error > {
1400
1406
let hash = block. post_hash ( ) ;
1401
1407
let number = * block. header . number ( ) ;
1408
+ let info = self . client . info ( ) ;
1402
1409
1403
- // early exit if block already in chain, otherwise the check for
1404
- // epoch changes will error when trying to re-import an epoch change
1405
- match self . client . status ( hash) {
1406
- Ok ( sp_blockchain:: BlockStatus :: InChain ) => {
1407
- // When re-importing existing block strip away intermediates.
1408
- let _ = block. remove_intermediate :: < BabeIntermediate < Block > > ( INTERMEDIATE_KEY ) ;
1409
- block. fork_choice = Some ( ForkChoiceStrategy :: Custom ( false ) ) ;
1410
- return self . inner . import_block ( block, new_cache) . await . map_err ( Into :: into)
1411
- } ,
1412
- Ok ( sp_blockchain:: BlockStatus :: Unknown ) => { } ,
1413
- Err ( e) => return Err ( ConsensusError :: ClientImport ( e. to_string ( ) ) ) ,
1410
+ let block_status = self
1411
+ . client
1412
+ . status ( hash)
1413
+ . map_err ( |e| ConsensusError :: ClientImport ( e. to_string ( ) ) ) ?;
1414
+
1415
+ // Skip babe logic if block already in chain or importing blocks during initial sync,
1416
+ // otherwise the check for epoch changes will error because trying to re-import an
1417
+ // epoch change or because of missing epoch data in the tree, respectivelly.
1418
+ if info. block_gap . map_or ( false , |( s, e) | s <= number && number <= e) ||
1419
+ block_status == BlockStatus :: InChain
1420
+ {
1421
+ // When re-importing existing block strip away intermediates.
1422
+ // In case of initial sync intermediates should not be present...
1423
+ let _ = block. remove_intermediate :: < BabeIntermediate < Block > > ( INTERMEDIATE_KEY ) ;
1424
+ block. fork_choice = Some ( ForkChoiceStrategy :: Custom ( false ) ) ;
1425
+ return self . inner . import_block ( block, new_cache) . await . map_err ( Into :: into)
1414
1426
}
1415
1427
1416
1428
if block. with_state ( ) {
@@ -1506,8 +1518,6 @@ where
1506
1518
) ) ,
1507
1519
}
1508
1520
1509
- let info = self . client . info ( ) ;
1510
-
1511
1521
if let Some ( next_epoch_descriptor) = next_epoch_digest {
1512
1522
old_epoch_changes = Some ( ( * epoch_changes) . clone ( ) ) ;
1513
1523
@@ -1701,9 +1711,6 @@ where
1701
1711
Client : HeaderBackend < Block > + HeaderMetadata < Block , Error = sp_blockchain:: Error > ,
1702
1712
{
1703
1713
let info = client. info ( ) ;
1704
- if info. block_gap . is_none ( ) {
1705
- epoch_changes. clear_gap ( ) ;
1706
- }
1707
1714
1708
1715
let finalized_slot = {
1709
1716
let finalized_header = client
0 commit comments