@@ -2241,3 +2241,49 @@ func BenchmarkBlockChain_1x1000Executions(b *testing.B) {
2241
2241
}
2242
2242
benchmarkLargeNumberOfValueToNonexisting (b , numTxs , numBlocks , recipientFn , dataFn )
2243
2243
}
2244
+
2245
+ // Tests that importing a some old blocks, where all blocks are before the
2246
+ // pruning point.
2247
+ // This internally leads to a sidechain import, since the blocks trigger an
2248
+ // ErrPrunedAncestor error.
2249
+ // This may e.g. happen if
2250
+ // 1. Downloader rollbacks a batch of inserted blocks and exits
2251
+ // 2. Downloader starts to sync again
2252
+ // 3. The blocks fetched are all known and canonical blocks
2253
+ func TestSideImportPrunedBlocks (t * testing.T ) {
2254
+ // Generate a canonical chain to act as the main dataset
2255
+ engine := ethash .NewFaker ()
2256
+ db := rawdb .NewMemoryDatabase ()
2257
+ genesis := new (Genesis ).MustCommit (db )
2258
+
2259
+ // Generate and import the canonical chain
2260
+ blocks , _ := GenerateChain (params .TestChainConfig , genesis , engine , db , 2 * TriesInMemory , nil )
2261
+ diskdb := rawdb .NewMemoryDatabase ()
2262
+ new (Genesis ).MustCommit (diskdb )
2263
+ chain , err := NewBlockChain (diskdb , nil , params .TestChainConfig , engine , vm.Config {}, nil )
2264
+ if err != nil {
2265
+ t .Fatalf ("failed to create tester chain: %v" , err )
2266
+ }
2267
+ if n , err := chain .InsertChain (blocks ); err != nil {
2268
+ t .Fatalf ("block %d: failed to insert into chain: %v" , n , err )
2269
+ }
2270
+
2271
+ lastPrunedIndex := len (blocks ) - TriesInMemory - 1
2272
+ lastPrunedBlock := blocks [lastPrunedIndex ]
2273
+
2274
+ // Verify pruning of lastPrunedBlock
2275
+ if chain .HasBlockAndState (lastPrunedBlock .Hash (), lastPrunedBlock .NumberU64 ()) {
2276
+ t .Errorf ("Block %d not pruned" , lastPrunedBlock .NumberU64 ())
2277
+ }
2278
+ firstNonPrunedBlock := blocks [len (blocks )- TriesInMemory ]
2279
+ // Verify firstNonPrunedBlock is not pruned
2280
+ if ! chain .HasBlockAndState (firstNonPrunedBlock .Hash (), firstNonPrunedBlock .NumberU64 ()) {
2281
+ t .Errorf ("Block %d pruned" , firstNonPrunedBlock .NumberU64 ())
2282
+ }
2283
+ // Now re-import some old blocks
2284
+ blockToReimport := blocks [5 :8 ]
2285
+ _ , err = chain .InsertChain (blockToReimport )
2286
+ if err != nil {
2287
+ t .Errorf ("Got error, %v" , err )
2288
+ }
2289
+ }
0 commit comments