@@ -3758,3 +3758,112 @@ func TestSetCanonical(t *testing.T) {
3758
3758
chain .SetCanonical (canon [TriesInMemory - 1 ])
3759
3759
verify (canon [TriesInMemory - 1 ])
3760
3760
}
3761
+
3762
+ // TestCanonicalHashMarker tests all the canonical hash markers are updated/deleted
3763
+ // correctly in case reorg is called.
3764
+ func TestCanonicalHashMarker (t * testing.T ) {
3765
+ var cases = []struct {
3766
+ forkA int
3767
+ forkB int
3768
+ }{
3769
+ // ForkA: 10 blocks
3770
+ // ForkB: 1 blocks
3771
+ //
3772
+ // reorged:
3773
+ // markers [2, 10] should be deleted
3774
+ // markers [1] should be updated
3775
+ {10 , 1 },
3776
+
3777
+ // ForkA: 10 blocks
3778
+ // ForkB: 2 blocks
3779
+ //
3780
+ // reorged:
3781
+ // markers [3, 10] should be deleted
3782
+ // markers [1, 2] should be updated
3783
+ {10 , 2 },
3784
+
3785
+ // ForkA: 10 blocks
3786
+ // ForkB: 10 blocks
3787
+ //
3788
+ // reorged:
3789
+ // markers [1, 10] should be updated
3790
+ {10 , 10 },
3791
+
3792
+ // ForkA: 10 blocks
3793
+ // ForkB: 11 blocks
3794
+ //
3795
+ // reorged:
3796
+ // markers [1, 11] should be updated
3797
+ {10 , 11 },
3798
+ }
3799
+ for _ , c := range cases {
3800
+ var (
3801
+ db = rawdb .NewMemoryDatabase ()
3802
+ gspec = & Genesis {
3803
+ Config : params .TestChainConfig ,
3804
+ Alloc : GenesisAlloc {},
3805
+ BaseFee : big .NewInt (params .InitialBaseFee ),
3806
+ }
3807
+ genesis = gspec .MustCommit (db )
3808
+ engine = ethash .NewFaker ()
3809
+ )
3810
+ forkA , _ := GenerateChain (params .TestChainConfig , genesis , engine , db , c .forkA , func (i int , gen * BlockGen ) {})
3811
+ forkB , _ := GenerateChain (params .TestChainConfig , genesis , engine , db , c .forkB , func (i int , gen * BlockGen ) {})
3812
+
3813
+ // Initialize test chain
3814
+ diskdb := rawdb .NewMemoryDatabase ()
3815
+ gspec .MustCommit (diskdb )
3816
+ chain , err := NewBlockChain (diskdb , nil , params .TestChainConfig , engine , vm.Config {}, nil , nil )
3817
+ if err != nil {
3818
+ t .Fatalf ("failed to create tester chain: %v" , err )
3819
+ }
3820
+ // Insert forkA and forkB, the canonical should on forkA still
3821
+ if n , err := chain .InsertChain (forkA ); err != nil {
3822
+ t .Fatalf ("block %d: failed to insert into chain: %v" , n , err )
3823
+ }
3824
+ if n , err := chain .InsertChain (forkB ); err != nil {
3825
+ t .Fatalf ("block %d: failed to insert into chain: %v" , n , err )
3826
+ }
3827
+
3828
+ verify := func (head * types.Block ) {
3829
+ if chain .CurrentBlock ().Hash () != head .Hash () {
3830
+ t .Fatalf ("Unexpected block hash, want %x, got %x" , head .Hash (), chain .CurrentBlock ().Hash ())
3831
+ }
3832
+ if chain .CurrentFastBlock ().Hash () != head .Hash () {
3833
+ t .Fatalf ("Unexpected fast block hash, want %x, got %x" , head .Hash (), chain .CurrentFastBlock ().Hash ())
3834
+ }
3835
+ if chain .CurrentHeader ().Hash () != head .Hash () {
3836
+ t .Fatalf ("Unexpected head header, want %x, got %x" , head .Hash (), chain .CurrentHeader ().Hash ())
3837
+ }
3838
+ if ! chain .HasState (head .Root ()) {
3839
+ t .Fatalf ("Lost block state %v %x" , head .Number (), head .Hash ())
3840
+ }
3841
+ }
3842
+
3843
+ // Switch canonical chain to forkB if necessary
3844
+ if len (forkA ) < len (forkB ) {
3845
+ verify (forkB [len (forkB )- 1 ])
3846
+ } else {
3847
+ verify (forkA [len (forkA )- 1 ])
3848
+ chain .SetCanonical (forkB [len (forkB )- 1 ])
3849
+ verify (forkB [len (forkB )- 1 ])
3850
+ }
3851
+
3852
+ // Ensure all hash markers are updated correctly
3853
+ for i := 0 ; i < len (forkB ); i ++ {
3854
+ block := forkB [i ]
3855
+ hash := chain .GetCanonicalHash (block .NumberU64 ())
3856
+ if hash != block .Hash () {
3857
+ t .Fatalf ("Unexpected canonical hash %d" , block .NumberU64 ())
3858
+ }
3859
+ }
3860
+ if c .forkA > c .forkB {
3861
+ for i := uint64 (c .forkB ) + 1 ; i <= uint64 (c .forkA ); i ++ {
3862
+ hash := chain .GetCanonicalHash (i )
3863
+ if hash != (common.Hash {}) {
3864
+ t .Fatalf ("Unexpected canonical hash %d" , i )
3865
+ }
3866
+ }
3867
+ }
3868
+ }
3869
+ }
0 commit comments