github.com/electroneum/electroneum-sc@v0.0.0-20230105223411-3bc1d078281e/core/forkid/forkid_test.go (about)

     1  // Copyright 2019 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package forkid
    18  
    19  import (
    20  	"bytes"
    21  	"math"
    22  	"math/big"
    23  	"testing"
    24  
    25  	"github.com/electroneum/electroneum-sc/common"
    26  	"github.com/electroneum/electroneum-sc/params"
    27  	"github.com/electroneum/electroneum-sc/rlp"
    28  )
    29  
    30  var (
    31  	mainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
    32  	mainnetChainConfig = params.ChainConfig{
    33  		ChainID:             big.NewInt(1),
    34  		HomesteadBlock:      big.NewInt(1_150_000),
    35  		DAOForkBlock:        big.NewInt(1_920_000),
    36  		DAOForkSupport:      true,
    37  		EIP150Block:         big.NewInt(2_463_000),
    38  		EIP150Hash:          common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    39  		EIP155Block:         big.NewInt(2_675_000),
    40  		EIP158Block:         big.NewInt(2_675_000),
    41  		ByzantiumBlock:      big.NewInt(4_370_000),
    42  		ConstantinopleBlock: big.NewInt(7_280_000),
    43  		PetersburgBlock:     big.NewInt(7_280_000),
    44  		IstanbulBlock:       big.NewInt(9_069_000),
    45  		MuirGlacierBlock:    big.NewInt(9_200_000),
    46  		BerlinBlock:         big.NewInt(12_244_000),
    47  		LondonBlock:         big.NewInt(12_965_000),
    48  		ArrowGlacierBlock:   big.NewInt(13_773_000),
    49  	}
    50  
    51  	ropstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
    52  	ropstenChainConfig = params.ChainConfig{
    53  		ChainID:                 big.NewInt(3),
    54  		HomesteadBlock:          big.NewInt(0),
    55  		DAOForkBlock:            nil,
    56  		DAOForkSupport:          true,
    57  		EIP150Block:             big.NewInt(0),
    58  		EIP150Hash:              common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
    59  		EIP155Block:             big.NewInt(10),
    60  		EIP158Block:             big.NewInt(10),
    61  		ByzantiumBlock:          big.NewInt(1_700_000),
    62  		ConstantinopleBlock:     big.NewInt(4_230_000),
    63  		PetersburgBlock:         big.NewInt(4_939_394),
    64  		IstanbulBlock:           big.NewInt(6_485_846),
    65  		MuirGlacierBlock:        big.NewInt(7_117_117),
    66  		BerlinBlock:             big.NewInt(9_812_189),
    67  		LondonBlock:             big.NewInt(10_499_401),
    68  		TerminalTotalDifficulty: big.NewInt(43531756765713534),
    69  	}
    70  )
    71  
    72  // TestCreation tests that different genesis and fork rule combinations result in
    73  // the correct fork ID.
    74  func TestCreation(t *testing.T) {
    75  	mergeConfig := mainnetChainConfig
    76  	mergeConfig.MergeForkBlock = big.NewInt(15000000)
    77  	type testcase struct {
    78  		head uint64
    79  		want ID
    80  	}
    81  	tests := []struct {
    82  		config  *params.ChainConfig
    83  		genesis common.Hash
    84  		cases   []testcase
    85  	}{
    86  		// Mainnet test cases
    87  		{
    88  			&mainnetChainConfig,
    89  			mainnetGenesisHash,
    90  			[]testcase{
    91  				{0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}},         // Unsynced
    92  				{1149999, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}},   // Last Frontier block
    93  				{1150000, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}},   // First Homestead block
    94  				{1919999, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}},   // Last Homestead block
    95  				{1920000, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}},   // First DAO block
    96  				{2462999, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}},   // Last DAO block
    97  				{2463000, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}},   // First Tangerine block
    98  				{2674999, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}},   // Last Tangerine block
    99  				{2675000, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}},   // First Spurious block
   100  				{4369999, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}},   // Last Spurious block
   101  				{4370000, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}},   // First Byzantium block
   102  				{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}},   // Last Byzantium block
   103  				{7280000, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}},   // First and last Constantinople, first Petersburg block
   104  				{9068999, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}},   // Last Petersburg block
   105  				{9069000, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}},   // First Istanbul and first Muir Glacier block
   106  				{9199999, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}},   // Last Istanbul and first Muir Glacier block
   107  				{9200000, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}},  // First Muir Glacier block
   108  				{12243999, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block
   109  				{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block
   110  				{12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block
   111  				{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block
   112  				{13772999, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block
   113  				{13773000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}},        // First Arrow Glacier block
   114  				{20000000, ID{Hash: checksumToBytes(0x20c327fc), Next: 0}},        // Future Arrow Glacier block
   115  			},
   116  		},
   117  		// Ropsten test cases
   118  		{
   119  			&ropstenChainConfig,
   120  			ropstenGenesisHash,
   121  			[]testcase{
   122  				{0, ID{Hash: checksumToBytes(0x30c7ddbc), Next: 10}},              // Unsynced, last Frontier, Homestead and first Tangerine block
   123  				{9, ID{Hash: checksumToBytes(0x30c7ddbc), Next: 10}},              // Last Tangerine block
   124  				{10, ID{Hash: checksumToBytes(0x63760190), Next: 1700000}},        // First Spurious block
   125  				{1699999, ID{Hash: checksumToBytes(0x63760190), Next: 1700000}},   // Last Spurious block
   126  				{1700000, ID{Hash: checksumToBytes(0x3ea159c7), Next: 4230000}},   // First Byzantium block
   127  				{4229999, ID{Hash: checksumToBytes(0x3ea159c7), Next: 4230000}},   // Last Byzantium block
   128  				{4230000, ID{Hash: checksumToBytes(0x97b544f3), Next: 4939394}},   // First Constantinople block
   129  				{4939393, ID{Hash: checksumToBytes(0x97b544f3), Next: 4939394}},   // Last Constantinople block
   130  				{4939394, ID{Hash: checksumToBytes(0xd6e2149b), Next: 6485846}},   // First Petersburg block
   131  				{6485845, ID{Hash: checksumToBytes(0xd6e2149b), Next: 6485846}},   // Last Petersburg block
   132  				{6485846, ID{Hash: checksumToBytes(0x4bc66396), Next: 7117117}},   // First Istanbul block
   133  				{7117116, ID{Hash: checksumToBytes(0x4bc66396), Next: 7117117}},   // Last Istanbul block
   134  				{7117117, ID{Hash: checksumToBytes(0x6727ef90), Next: 9812189}},   // First Muir Glacier block
   135  				{9812188, ID{Hash: checksumToBytes(0x6727ef90), Next: 9812189}},   // Last Muir Glacier block
   136  				{9812189, ID{Hash: checksumToBytes(0xa157d377), Next: 10499401}},  // First Berlin block
   137  				{10499400, ID{Hash: checksumToBytes(0xa157d377), Next: 10499401}}, // Last Berlin block
   138  				{10499401, ID{Hash: checksumToBytes(0x7119b6b3), Next: 0}},        // First London block
   139  				{11000000, ID{Hash: checksumToBytes(0x7119b6b3), Next: 0}},        // Future London block
   140  			},
   141  		},
   142  		// Merge test cases
   143  		{
   144  			&mergeConfig,
   145  			mainnetGenesisHash,
   146  			[]testcase{
   147  				{0, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}},         // Unsynced
   148  				{1149999, ID{Hash: checksumToBytes(0xfc64ec04), Next: 1150000}},   // Last Frontier block
   149  				{1150000, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}},   // First Homestead block
   150  				{1919999, ID{Hash: checksumToBytes(0x97c2c34c), Next: 1920000}},   // Last Homestead block
   151  				{1920000, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}},   // First DAO block
   152  				{2462999, ID{Hash: checksumToBytes(0x91d1f948), Next: 2463000}},   // Last DAO block
   153  				{2463000, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}},   // First Tangerine block
   154  				{2674999, ID{Hash: checksumToBytes(0x7a64da13), Next: 2675000}},   // Last Tangerine block
   155  				{2675000, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}},   // First Spurious block
   156  				{4369999, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}},   // Last Spurious block
   157  				{4370000, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}},   // First Byzantium block
   158  				{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}},   // Last Byzantium block
   159  				{7280000, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}},   // First and last Constantinople, first Petersburg block
   160  				{9068999, ID{Hash: checksumToBytes(0x668db0af), Next: 9069000}},   // Last Petersburg block
   161  				{9069000, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}},   // First Istanbul and first Muir Glacier block
   162  				{9199999, ID{Hash: checksumToBytes(0x879d6e30), Next: 9200000}},   // Last Istanbul and first Muir Glacier block
   163  				{9200000, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}},  // First Muir Glacier block
   164  				{12243999, ID{Hash: checksumToBytes(0xe029e991), Next: 12244000}}, // Last Muir Glacier block
   165  				{12244000, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // First Berlin block
   166  				{12964999, ID{Hash: checksumToBytes(0x0eb440f6), Next: 12965000}}, // Last Berlin block
   167  				{12965000, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // First London block
   168  				{13772999, ID{Hash: checksumToBytes(0xb715077d), Next: 13773000}}, // Last London block
   169  				{13773000, ID{Hash: checksumToBytes(0x20c327fc), Next: 15000000}}, // First Arrow Glacier block
   170  				{15000000, ID{Hash: checksumToBytes(0xe3abe201), Next: 0}},        // First Merge Start block
   171  				{20000000, ID{Hash: checksumToBytes(0xe3abe201), Next: 0}},        // Future Merge Start block
   172  			},
   173  		},
   174  	}
   175  	for i, tt := range tests {
   176  		for j, ttt := range tt.cases {
   177  			if have := NewID(tt.config, tt.genesis, ttt.head); have != ttt.want {
   178  				t.Errorf("test %d, case %d: fork ID mismatch: have %x, want %x", i, j, have, ttt.want)
   179  			}
   180  		}
   181  	}
   182  }
   183  
   184  // TestValidation tests that a local peer correctly validates and accepts a remote
   185  // fork ID.
   186  func TestValidation(t *testing.T) {
   187  	tests := []struct {
   188  		head uint64
   189  		id   ID
   190  		err  error
   191  	}{
   192  		// Local is mainnet Petersburg, remote announces the same. No future fork is announced.
   193  		{7987396, ID{Hash: checksumToBytes(0x668db0af), Next: 0}, nil},
   194  
   195  		// Local is mainnet Petersburg, remote announces the same. Remote also announces a next fork
   196  		// at block 0xffffffff, but that is uncertain.
   197  		{7987396, ID{Hash: checksumToBytes(0x668db0af), Next: math.MaxUint64}, nil},
   198  
   199  		// Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces
   200  		// also Byzantium, but it's not yet aware of Petersburg (e.g. non updated node before the fork).
   201  		// In this case we don't know if Petersburg passed yet or not.
   202  		{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: 0}, nil},
   203  
   204  		// Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces
   205  		// also Byzantium, and it's also aware of Petersburg (e.g. updated node before the fork). We
   206  		// don't know if Petersburg passed yet (will pass) or not.
   207  		{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}, nil},
   208  
   209  		// Local is mainnet currently in Byzantium only (so it's aware of Petersburg), remote announces
   210  		// also Byzantium, and it's also aware of some random fork (e.g. misconfigured Petersburg). As
   211  		// neither forks passed at neither nodes, they may mismatch, but we still connect for now.
   212  		{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: math.MaxUint64}, nil},
   213  
   214  		// Local is mainnet exactly on Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote
   215  		// is simply out of sync, accept.
   216  		{7280000, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}, nil},
   217  
   218  		// Local is mainnet Petersburg, remote announces Byzantium + knowledge about Petersburg. Remote
   219  		// is simply out of sync, accept.
   220  		{7987396, ID{Hash: checksumToBytes(0xa00bc324), Next: 7280000}, nil},
   221  
   222  		// Local is mainnet Petersburg, remote announces Spurious + knowledge about Byzantium. Remote
   223  		// is definitely out of sync. It may or may not need the Petersburg update, we don't know yet.
   224  		{7987396, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}, nil},
   225  
   226  		// Local is mainnet Byzantium, remote announces Petersburg. Local is out of sync, accept.
   227  		{7279999, ID{Hash: checksumToBytes(0x668db0af), Next: 0}, nil},
   228  
   229  		// Local is mainnet Spurious, remote announces Byzantium, but is not aware of Petersburg. Local
   230  		// out of sync. Local also knows about a future fork, but that is uncertain yet.
   231  		{4369999, ID{Hash: checksumToBytes(0xa00bc324), Next: 0}, nil},
   232  
   233  		// Local is mainnet Petersburg. remote announces Byzantium but is not aware of further forks.
   234  		// Remote needs software update.
   235  		{7987396, ID{Hash: checksumToBytes(0xa00bc324), Next: 0}, ErrRemoteStale},
   236  
   237  		// Local is mainnet Petersburg, and isn't aware of more forks. Remote announces Petersburg +
   238  		// 0xffffffff. Local needs software update, reject.
   239  		{7987396, ID{Hash: checksumToBytes(0x5cddc0e1), Next: 0}, ErrLocalIncompatibleOrStale},
   240  
   241  		// Local is mainnet Byzantium, and is aware of Petersburg. Remote announces Petersburg +
   242  		// 0xffffffff. Local needs software update, reject.
   243  		{7279999, ID{Hash: checksumToBytes(0x5cddc0e1), Next: 0}, ErrLocalIncompatibleOrStale},
   244  
   245  		// Local is mainnet Petersburg, remote is Rinkeby Petersburg.
   246  		{7987396, ID{Hash: checksumToBytes(0xafec6b27), Next: 0}, ErrLocalIncompatibleOrStale},
   247  
   248  		// Local is mainnet Arrow Glacier, far in the future. Remote announces Gopherium (non existing fork)
   249  		// at some future block 88888888, for itself, but past block for local. Local is incompatible.
   250  		//
   251  		// This case detects non-upgraded nodes with majority hash power (typical Ropsten mess).
   252  		{88888888, ID{Hash: checksumToBytes(0x20c327fc), Next: 88888888}, ErrLocalIncompatibleOrStale},
   253  
   254  		// Local is mainnet Byzantium. Remote is also in Byzantium, but announces Gopherium (non existing
   255  		// fork) at block 7279999, before Petersburg. Local is incompatible.
   256  		{7279999, ID{Hash: checksumToBytes(0xa00bc324), Next: 7279999}, ErrLocalIncompatibleOrStale},
   257  	}
   258  	for i, tt := range tests {
   259  		filter := newFilter(&mainnetChainConfig, mainnetGenesisHash, func() uint64 { return tt.head })
   260  		if err := filter(tt.id); err != tt.err {
   261  			t.Errorf("test %d: validation error mismatch: have %v, want %v", i, err, tt.err)
   262  		}
   263  	}
   264  }
   265  
   266  // Tests that IDs are properly RLP encoded (specifically important because we
   267  // use uint32 to store the hash, but we need to encode it as [4]byte).
   268  func TestEncoding(t *testing.T) {
   269  	tests := []struct {
   270  		id   ID
   271  		want []byte
   272  	}{
   273  		{ID{Hash: checksumToBytes(0), Next: 0}, common.Hex2Bytes("c6840000000080")},
   274  		{ID{Hash: checksumToBytes(0xdeadbeef), Next: 0xBADDCAFE}, common.Hex2Bytes("ca84deadbeef84baddcafe,")},
   275  		{ID{Hash: checksumToBytes(math.MaxUint32), Next: math.MaxUint64}, common.Hex2Bytes("ce84ffffffff88ffffffffffffffff")},
   276  	}
   277  	for i, tt := range tests {
   278  		have, err := rlp.EncodeToBytes(tt.id)
   279  		if err != nil {
   280  			t.Errorf("test %d: failed to encode forkid: %v", i, err)
   281  			continue
   282  		}
   283  		if !bytes.Equal(have, tt.want) {
   284  			t.Errorf("test %d: RLP mismatch: have %x, want %x", i, have, tt.want)
   285  		}
   286  	}
   287  }