@@ -3676,3 +3676,85 @@ func TestEIP1559Transition(t *testing.T) {
3676
3676
t .Fatalf ("sender balance incorrect: expected %d, got %d" , expected , actual )
3677
3677
}
3678
3678
}
3679
+
3680
+ // Tests the scenario the chain is requested to another point with the missing state.
3681
+ // It expects the state is recovered and all relevant chain markers are set correctly.
3682
+ func TestSetCanonical (t * testing.T ) {
3683
+ //log.Root().SetHandler(log.LvlFilterHandler(log.LvlDebug, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
3684
+
3685
+ var (
3686
+ db = rawdb .NewMemoryDatabase ()
3687
+ key , _ = crypto .HexToECDSA ("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291" )
3688
+ address = crypto .PubkeyToAddress (key .PublicKey )
3689
+ funds = big .NewInt (100000000000000000 )
3690
+ gspec = & Genesis {
3691
+ Config : params .TestChainConfig ,
3692
+ Alloc : GenesisAlloc {address : {Balance : funds }},
3693
+ BaseFee : big .NewInt (params .InitialBaseFee ),
3694
+ }
3695
+ genesis = gspec .MustCommit (db )
3696
+ signer = types .LatestSigner (gspec .Config )
3697
+ engine = ethash .NewFaker ()
3698
+ )
3699
+ // Generate and import the canonical chain
3700
+ canon , _ := GenerateChain (params .TestChainConfig , genesis , engine , db , 2 * TriesInMemory , func (i int , gen * BlockGen ) {
3701
+ tx , err := types .SignTx (types .NewTransaction (gen .TxNonce (address ), common.Address {0x00 }, big .NewInt (1000 ), params .TxGas , gen .header .BaseFee , nil ), signer , key )
3702
+ if err != nil {
3703
+ panic (err )
3704
+ }
3705
+ gen .AddTx (tx )
3706
+ })
3707
+ diskdb := rawdb .NewMemoryDatabase ()
3708
+ gspec .MustCommit (diskdb )
3709
+
3710
+ chain , err := NewBlockChain (diskdb , nil , params .TestChainConfig , engine , vm.Config {}, nil , nil )
3711
+ if err != nil {
3712
+ t .Fatalf ("failed to create tester chain: %v" , err )
3713
+ }
3714
+ if n , err := chain .InsertChain (canon ); err != nil {
3715
+ t .Fatalf ("block %d: failed to insert into chain: %v" , n , err )
3716
+ }
3717
+
3718
+ // Generate the side chain and import them
3719
+ side , _ := GenerateChain (params .TestChainConfig , genesis , engine , db , 2 * TriesInMemory , func (i int , gen * BlockGen ) {
3720
+ tx , err := types .SignTx (types .NewTransaction (gen .TxNonce (address ), common.Address {0x00 }, big .NewInt (1 ), params .TxGas , gen .header .BaseFee , nil ), signer , key )
3721
+ if err != nil {
3722
+ panic (err )
3723
+ }
3724
+ gen .AddTx (tx )
3725
+ })
3726
+ for _ , block := range side {
3727
+ err := chain .InsertBlockWithoutSetHead (block )
3728
+ if err != nil {
3729
+ t .Fatalf ("Failed to insert into chain: %v" , err )
3730
+ }
3731
+ }
3732
+ for _ , block := range side {
3733
+ got := chain .GetBlockByHash (block .Hash ())
3734
+ if got == nil {
3735
+ t .Fatalf ("Lost the inserted block" )
3736
+ }
3737
+ }
3738
+
3739
+ // Set the chain head to the side chain, ensure all the relevant markers are updated.
3740
+ verify := func (head * types.Block ) {
3741
+ if chain .CurrentBlock ().Hash () != head .Hash () {
3742
+ t .Fatalf ("Unexpected block hash, want %x, got %x" , head .Hash (), chain .CurrentBlock ().Hash ())
3743
+ }
3744
+ if chain .CurrentFastBlock ().Hash () != head .Hash () {
3745
+ t .Fatalf ("Unexpected fast block hash, want %x, got %x" , head .Hash (), chain .CurrentFastBlock ().Hash ())
3746
+ }
3747
+ if chain .CurrentHeader ().Hash () != head .Hash () {
3748
+ t .Fatalf ("Unexpected head header, want %x, got %x" , head .Hash (), chain .CurrentHeader ().Hash ())
3749
+ }
3750
+ if ! chain .HasState (head .Root ()) {
3751
+ t .Fatalf ("Lost block state %v %x" , head .Number (), head .Hash ())
3752
+ }
3753
+ }
3754
+ chain .SetCanonical (side [len (side )- 1 ])
3755
+ verify (side [len (side )- 1 ])
3756
+
3757
+ // Reset the chain head to original chain
3758
+ chain .SetCanonical (canon [TriesInMemory - 1 ])
3759
+ verify (canon [TriesInMemory - 1 ])
3760
+ }
0 commit comments