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