@@ -755,7 +755,10 @@ where
755755 Err ( e) => PersistedEpoch :: Regular ( e) ,
756756 }
757757 }
758- } else if epoch. is_genesis ( ) && !self . epochs . values ( ) . all ( |e| e. is_genesis ( ) ) {
758+ } else if epoch. is_genesis ( ) &&
759+ !self . epochs . is_empty ( ) &&
760+ !self . epochs . values ( ) . any ( |e| e. is_genesis ( ) )
761+ {
759762 // There's a genesis epoch imported when we already have an active epoch.
760763 // This happens after the warp sync as the ancient blocks download start.
761764 // We need to start tracking gap epochs here.
@@ -1170,15 +1173,17 @@ mod tests {
11701173 epoch_changes. clear_gap ( ) ;
11711174
11721175 // Check that both epochs are available.
1173- epoch_changes
1176+ let epoch_a = epoch_changes
11741177 . epoch_data_for_child_of ( & is_descendent_of, b"A" , 1 , 101 , & make_genesis)
11751178 . unwrap ( )
11761179 . unwrap ( ) ;
11771180
1178- epoch_changes
1181+ let epoch_x = epoch_changes
11791182 . epoch_data_for_child_of ( & is_descendent_of, b"X" , 1 , 1001 , & make_genesis)
11801183 . unwrap ( )
11811184 . unwrap ( ) ;
1185+
1186+ assert ! ( epoch_a != epoch_x)
11821187 }
11831188
11841189 #[ test]
@@ -1288,4 +1293,108 @@ mod tests {
12881293 epoch_changes. clear_gap ( ) ;
12891294 assert ! ( epoch_changes. gap. is_none( ) ) ;
12901295 }
1296+
1297+ /// Test that ensures that the gap is not enabled when there's still genesis
1298+ /// epochs imported, regardless of whether there are already other further
1299+ /// epochs imported descending from such genesis epochs.
1300+ #[ test]
1301+ fn gap_is_not_enabled_when_at_least_one_genesis_epoch_is_still_imported ( ) {
1302+ // A (#1) - B (#201)
1303+ // /
1304+ // 0 - C (#1)
1305+ //
1306+ // The epoch duration is 100 slots, each of these blocks represents
1307+ // an epoch change block. block B starts a new epoch at #201 since the
1308+ // genesis epoch spans two epochs.
1309+
1310+ let is_descendent_of = |base : & Hash , block : & Hash | -> Result < bool , TestError > {
1311+ match ( base, block) {
1312+ ( b"0" , _) => Ok ( true ) ,
1313+ ( b"A" , b"B" ) => Ok ( true ) ,
1314+ _ => Ok ( false ) ,
1315+ }
1316+ } ;
1317+
1318+ let duration = 100 ;
1319+ let make_genesis = |slot| Epoch { start_slot : slot, duration } ;
1320+ let mut epoch_changes = EpochChanges :: new ( ) ;
1321+ let next_descriptor = ( ) ;
1322+
1323+ // insert genesis epoch for A at slot 1
1324+ {
1325+ let genesis_epoch_a_descriptor = epoch_changes
1326+ . epoch_descriptor_for_child_of ( & is_descendent_of, b"0" , 0 , 1 )
1327+ . unwrap ( )
1328+ . unwrap ( ) ;
1329+
1330+ let incremented_epoch = epoch_changes
1331+ . viable_epoch ( & genesis_epoch_a_descriptor, & make_genesis)
1332+ . unwrap ( )
1333+ . increment ( next_descriptor. clone ( ) ) ;
1334+
1335+ epoch_changes
1336+ . import ( & is_descendent_of, * b"A" , 1 , * b"0" , incremented_epoch)
1337+ . unwrap ( ) ;
1338+ }
1339+
1340+ // insert regular epoch for B at slot 201, descending from A
1341+ {
1342+ let epoch_b_descriptor = epoch_changes
1343+ . epoch_descriptor_for_child_of ( & is_descendent_of, b"A" , 1 , 201 )
1344+ . unwrap ( )
1345+ . unwrap ( ) ;
1346+
1347+ let incremented_epoch = epoch_changes
1348+ . viable_epoch ( & epoch_b_descriptor, & make_genesis)
1349+ . unwrap ( )
1350+ . increment ( next_descriptor. clone ( ) ) ;
1351+
1352+ epoch_changes
1353+ . import ( & is_descendent_of, * b"B" , 201 , * b"A" , incremented_epoch)
1354+ . unwrap ( ) ;
1355+ }
1356+
1357+ // insert genesis epoch for C at slot 1000
1358+ {
1359+ let genesis_epoch_x_descriptor = epoch_changes
1360+ . epoch_descriptor_for_child_of ( & is_descendent_of, b"0" , 0 , 1000 )
1361+ . unwrap ( )
1362+ . unwrap ( ) ;
1363+
1364+ let incremented_epoch = epoch_changes
1365+ . viable_epoch ( & genesis_epoch_x_descriptor, & make_genesis)
1366+ . unwrap ( )
1367+ . increment ( next_descriptor. clone ( ) ) ;
1368+
1369+ epoch_changes
1370+ . import ( & is_descendent_of, * b"C" , 1 , * b"0" , incremented_epoch)
1371+ . unwrap ( ) ;
1372+ }
1373+
1374+ // Clearing the gap should be a no-op.
1375+ epoch_changes. clear_gap ( ) ;
1376+
1377+ // Check that all three epochs are available.
1378+ let epoch_a = epoch_changes
1379+ . epoch_data_for_child_of ( & is_descendent_of, b"A" , 1 , 10 , & make_genesis)
1380+ . unwrap ( )
1381+ . unwrap ( ) ;
1382+
1383+ let epoch_b = epoch_changes
1384+ . epoch_data_for_child_of ( & is_descendent_of, b"B" , 201 , 201 , & make_genesis)
1385+ . unwrap ( )
1386+ . unwrap ( ) ;
1387+
1388+ assert ! ( epoch_a != epoch_b) ;
1389+
1390+ // the genesis epoch A will span slots [1, 200] with epoch B starting at slot 201
1391+ assert_eq ! ( epoch_b. start_slot( ) , 201 ) ;
1392+
1393+ let epoch_c = epoch_changes
1394+ . epoch_data_for_child_of ( & is_descendent_of, b"C" , 1 , 1001 , & make_genesis)
1395+ . unwrap ( )
1396+ . unwrap ( ) ;
1397+
1398+ assert ! ( epoch_a != epoch_c) ;
1399+ }
12911400}
0 commit comments