github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/core/genesis_test.go (about)

     1  // Copyright 2017 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 core
    18  
    19  import (
    20  	"math/big"
    21  	"reflect"
    22  	"testing"
    23  
    24  	"github.com/davecgh/go-spew/spew"
    25  
    26  	"github.com/scroll-tech/go-ethereum/common"
    27  	"github.com/scroll-tech/go-ethereum/consensus/ethash"
    28  	"github.com/scroll-tech/go-ethereum/core/rawdb"
    29  	"github.com/scroll-tech/go-ethereum/core/vm"
    30  	"github.com/scroll-tech/go-ethereum/ethdb"
    31  	"github.com/scroll-tech/go-ethereum/params"
    32  )
    33  
    34  func TestInvalidCliqueConfig(t *testing.T) {
    35  	block := DefaultGoerliGenesisBlock()
    36  	block.ExtraData = []byte{}
    37  	if _, err := block.Commit(nil); err == nil {
    38  		t.Fatal("Expected error on invalid clique config")
    39  	}
    40  }
    41  
    42  func TestSetupGenesis(t *testing.T) {
    43  	var (
    44  		customghash = common.HexToHash("0x700380ab70d789c462c4e8f0db082842095321f390d0a3f25f400f0746db32bc")
    45  		customg     = Genesis{
    46  			Config: &params.ChainConfig{HomesteadBlock: big.NewInt(3)},
    47  			Alloc: GenesisAlloc{
    48  				{1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}},
    49  			},
    50  		}
    51  		oldcustomg = customg
    52  	)
    53  	oldcustomg.Config = &params.ChainConfig{HomesteadBlock: big.NewInt(2)}
    54  	tests := []struct {
    55  		name       string
    56  		fn         func(ethdb.Database) (*params.ChainConfig, common.Hash, error)
    57  		wantConfig *params.ChainConfig
    58  		wantHash   common.Hash
    59  		wantErr    error
    60  	}{
    61  		{
    62  			name: "genesis without ChainConfig",
    63  			fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
    64  				return SetupGenesisBlock(db, new(Genesis))
    65  			},
    66  			wantErr:    errGenesisNoConfig,
    67  			wantConfig: params.AllEthashProtocolChanges,
    68  		},
    69  		// {
    70  		// 	name: "no block in DB, genesis == nil",
    71  		// 	fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
    72  		// 		return SetupGenesisBlock(db, nil)
    73  		// 	},
    74  		// 	wantHash:   params.MainnetGenesisHash,
    75  		// 	wantConfig: params.MainnetChainConfig,
    76  		// },
    77  		// {
    78  		// 	name: "mainnet block in DB, genesis == nil",
    79  		// 	fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
    80  		// 		DefaultGenesisBlock().MustCommit(db)
    81  		// 		return SetupGenesisBlock(db, nil)
    82  		// 	},
    83  		// 	wantHash:   params.MainnetGenesisHash,
    84  		// 	wantConfig: params.MainnetChainConfig,
    85  		// },
    86  		{
    87  			name: "custom block in DB, genesis == nil",
    88  			fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
    89  				customg.MustCommit(db)
    90  				return SetupGenesisBlock(db, nil)
    91  			},
    92  			wantHash:   customghash,
    93  			wantConfig: customg.Config,
    94  		},
    95  		// {
    96  		// 	name: "custom block in DB, genesis == ropsten",
    97  		// 	fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
    98  		// 		customg.MustCommit(db)
    99  		// 		return SetupGenesisBlock(db, DefaultRopstenGenesisBlock())
   100  		// 	},
   101  		// 	wantErr:    &GenesisMismatchError{Stored: customghash, New: params.RopstenGenesisHash},
   102  		// 	wantHash:   params.RopstenGenesisHash,
   103  		// 	wantConfig: params.RopstenChainConfig,
   104  		// },
   105  		{
   106  			name: "compatible config in DB",
   107  			fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
   108  				oldcustomg.MustCommit(db)
   109  				return SetupGenesisBlock(db, &customg)
   110  			},
   111  			wantHash:   customghash,
   112  			wantConfig: customg.Config,
   113  		},
   114  		{
   115  			name: "incompatible config in DB",
   116  			fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) {
   117  				// Commit the 'old' genesis block with Homestead transition at #2.
   118  				// Advance to block #4, past the homestead transition block of customg.
   119  				genesis := oldcustomg.MustCommit(db)
   120  
   121  				bc, _ := NewBlockChain(db, nil, oldcustomg.Config, ethash.NewFullFaker(), vm.Config{}, nil, nil, false)
   122  				defer bc.Stop()
   123  
   124  				blocks, _ := GenerateChain(oldcustomg.Config, genesis, ethash.NewFaker(), db, 4, nil)
   125  				bc.InsertChain(blocks)
   126  				bc.CurrentBlock()
   127  				// This should return a compatibility error.
   128  				return SetupGenesisBlock(db, &customg)
   129  			},
   130  			wantHash:   customghash,
   131  			wantConfig: customg.Config,
   132  			wantErr: &params.ConfigCompatError{
   133  				What:         "Homestead fork block",
   134  				StoredConfig: big.NewInt(2),
   135  				NewConfig:    big.NewInt(3),
   136  				RewindTo:     1,
   137  			},
   138  		},
   139  	}
   140  
   141  	for _, test := range tests {
   142  		db := rawdb.NewMemoryDatabase()
   143  		config, hash, err := test.fn(db)
   144  		// Check the return values.
   145  		if !reflect.DeepEqual(err, test.wantErr) {
   146  			spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true}
   147  			t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr))
   148  		}
   149  		if !reflect.DeepEqual(config, test.wantConfig) {
   150  			t.Errorf("%s:\nreturned %v\nwant     %v", test.name, config, test.wantConfig)
   151  		}
   152  		if hash != test.wantHash {
   153  			t.Errorf("%s: returned hash %s, want %s", test.name, hash.Hex(), test.wantHash.Hex())
   154  		} else if err == nil {
   155  			// Check database content.
   156  			stored := rawdb.ReadBlock(db, test.wantHash, 0)
   157  			if stored.Hash() != test.wantHash {
   158  				t.Errorf("%s: block in DB has hash %s, want %s", test.name, stored.Hash(), test.wantHash)
   159  			}
   160  		}
   161  	}
   162  }
   163  
   164  // TestGenesisHashes checks the congruity of default genesis data to
   165  // corresponding hardcoded genesis hash values.
   166  func TestGenesisHashes(t *testing.T) {
   167  	for i, c := range []struct {
   168  		genesis *Genesis
   169  		want    common.Hash
   170  	}{
   171  		// {DefaultGenesisBlock(), params.MainnetGenesisHash},
   172  		// {DefaultGoerliGenesisBlock(), params.GoerliGenesisHash},
   173  		// {DefaultRopstenGenesisBlock(), params.RopstenGenesisHash},
   174  		// {DefaultRinkebyGenesisBlock(), params.RinkebyGenesisHash},
   175  		// {DefaultSepoliaGenesisBlock(), params.SepoliaGenesisHash},
   176  		// {DefaultScrollAlphaGenesisBlock(), params.ScrollAlphaGenesisHash},
   177  		{DefaultScrollSepoliaGenesisBlock(), params.ScrollSepoliaGenesisHash},
   178  		{DefaultScrollMainnetGenesisBlock(), params.ScrollMainnetGenesisHash},
   179  	} {
   180  		// Test via MustCommit
   181  		if have := c.genesis.MustCommit(rawdb.NewMemoryDatabase()).Hash(); have != c.want {
   182  			t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex())
   183  		}
   184  		// Test via ToBlock
   185  		if have := c.genesis.ToBlock(nil).Hash(); have != c.want {
   186  			t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex())
   187  		}
   188  	}
   189  }
   190  
   191  func TestGenesis_Commit(t *testing.T) {
   192  	genesis := &Genesis{
   193  		BaseFee: big.NewInt(params.InitialBaseFee),
   194  		Config:  params.TestChainConfig,
   195  		// difficulty is nil
   196  	}
   197  
   198  	db := rawdb.NewMemoryDatabase()
   199  	genesisBlock, err := genesis.Commit(db)
   200  	if err != nil {
   201  		t.Fatal(err)
   202  	}
   203  
   204  	if genesis.Difficulty != nil {
   205  		t.Fatalf("assumption wrong")
   206  	}
   207  
   208  	// This value should have been set as default in the ToBlock method.
   209  	if genesisBlock.Difficulty().Cmp(params.GenesisDifficulty) != 0 {
   210  		t.Errorf("assumption wrong: want: %d, got: %v", params.GenesisDifficulty, genesisBlock.Difficulty())
   211  	}
   212  
   213  	// Expect the stored total difficulty to be the difficulty of the genesis block.
   214  	stored := rawdb.ReadTd(db, genesisBlock.Hash(), genesisBlock.NumberU64())
   215  
   216  	if stored.Cmp(genesisBlock.Difficulty()) != 0 {
   217  		t.Errorf("inequal difficulty; stored: %v, genesisBlock: %v", stored, genesisBlock.Difficulty())
   218  	}
   219  }