github.com/theQRL/go-zond@v0.1.1/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 "encoding/json" 21 "math/big" 22 "reflect" 23 "testing" 24 25 "github.com/davecgh/go-spew/spew" 26 "github.com/theQRL/go-zond/common" 27 "github.com/theQRL/go-zond/consensus/ethash" 28 "github.com/theQRL/go-zond/core/rawdb" 29 "github.com/theQRL/go-zond/core/vm" 30 "github.com/theQRL/go-zond/params" 31 "github.com/theQRL/go-zond/trie" 32 "github.com/theQRL/go-zond/trie/triedb/pathdb" 33 "github.com/theQRL/go-zond/zonddb" 34 ) 35 36 func TestInvalidCliqueConfig(t *testing.T) { 37 block := DefaultGoerliGenesisBlock() 38 block.ExtraData = []byte{} 39 db := rawdb.NewMemoryDatabase() 40 if _, err := block.Commit(db, trie.NewDatabase(db, nil)); err == nil { 41 t.Fatal("Expected error on invalid clique config") 42 } 43 } 44 45 func TestSetupGenesis(t *testing.T) { 46 testSetupGenesis(t, rawdb.HashScheme) 47 testSetupGenesis(t, rawdb.PathScheme) 48 } 49 50 func testSetupGenesis(t *testing.T, scheme string) { 51 var ( 52 customghash = common.HexToHash("0x89c99d90b79719238d2645c7642f2c9295246e80775b38cfd162b696817fbd50") 53 customg = Genesis{ 54 Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3)}, 55 Alloc: GenesisAlloc{ 56 {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, 57 }, 58 } 59 oldcustomg = customg 60 ) 61 oldcustomg.Config = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(2)} 62 63 tests := []struct { 64 name string 65 fn func(zonddb.Database) (*params.ChainConfig, common.Hash, error) 66 wantConfig *params.ChainConfig 67 wantHash common.Hash 68 wantErr error 69 }{ 70 { 71 name: "genesis without ChainConfig", 72 fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) { 73 return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), new(Genesis)) 74 }, 75 wantErr: errGenesisNoConfig, 76 wantConfig: params.AllEthashProtocolChanges, 77 }, 78 { 79 name: "no block in DB, genesis == nil", 80 fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) { 81 return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), nil) 82 }, 83 wantHash: params.MainnetGenesisHash, 84 wantConfig: params.MainnetChainConfig, 85 }, 86 { 87 name: "mainnet block in DB, genesis == nil", 88 fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) { 89 DefaultGenesisBlock().MustCommit(db, trie.NewDatabase(db, newDbConfig(scheme))) 90 return SetupGenesisBlock(db, trie.NewDatabase(db, newDbConfig(scheme)), nil) 91 }, 92 wantHash: params.MainnetGenesisHash, 93 wantConfig: params.MainnetChainConfig, 94 }, 95 { 96 name: "custom block in DB, genesis == nil", 97 fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) { 98 tdb := trie.NewDatabase(db, newDbConfig(scheme)) 99 customg.Commit(db, tdb) 100 return SetupGenesisBlock(db, tdb, nil) 101 }, 102 wantHash: customghash, 103 wantConfig: customg.Config, 104 }, 105 { 106 name: "custom block in DB, genesis == goerli", 107 fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) { 108 tdb := trie.NewDatabase(db, newDbConfig(scheme)) 109 customg.Commit(db, tdb) 110 return SetupGenesisBlock(db, tdb, DefaultGoerliGenesisBlock()) 111 }, 112 wantErr: &GenesisMismatchError{Stored: customghash, New: params.GoerliGenesisHash}, 113 wantHash: params.GoerliGenesisHash, 114 wantConfig: params.GoerliChainConfig, 115 }, 116 { 117 name: "compatible config in DB", 118 fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) { 119 tdb := trie.NewDatabase(db, newDbConfig(scheme)) 120 oldcustomg.Commit(db, tdb) 121 return SetupGenesisBlock(db, tdb, &customg) 122 }, 123 wantHash: customghash, 124 wantConfig: customg.Config, 125 }, 126 { 127 name: "incompatible config in DB", 128 fn: func(db zonddb.Database) (*params.ChainConfig, common.Hash, error) { 129 // Commit the 'old' genesis block with Homestead transition at #2. 130 // Advance to block #4, past the homestead transition block of customg. 131 tdb := trie.NewDatabase(db, newDbConfig(scheme)) 132 oldcustomg.Commit(db, tdb) 133 134 bc, _ := NewBlockChain(db, DefaultCacheConfigWithScheme(scheme), &oldcustomg, nil, ethash.NewFullFaker(), vm.Config{}, nil, nil) 135 defer bc.Stop() 136 137 _, blocks, _ := GenerateChainWithGenesis(&oldcustomg, ethash.NewFaker(), 4, nil) 138 bc.InsertChain(blocks) 139 140 // This should return a compatibility error. 141 return SetupGenesisBlock(db, tdb, &customg) 142 }, 143 wantHash: customghash, 144 wantConfig: customg.Config, 145 wantErr: ¶ms.ConfigCompatError{ 146 What: "Homestead fork block", 147 StoredBlock: big.NewInt(2), 148 NewBlock: big.NewInt(3), 149 RewindToBlock: 1, 150 }, 151 }, 152 } 153 154 for _, test := range tests { 155 db := rawdb.NewMemoryDatabase() 156 config, hash, err := test.fn(db) 157 // Check the return values. 158 if !reflect.DeepEqual(err, test.wantErr) { 159 spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true} 160 t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr)) 161 } 162 if !reflect.DeepEqual(config, test.wantConfig) { 163 t.Errorf("%s:\nreturned %v\nwant %v", test.name, config, test.wantConfig) 164 } 165 if hash != test.wantHash { 166 t.Errorf("%s: returned hash %s, want %s", test.name, hash.Hex(), test.wantHash.Hex()) 167 } else if err == nil { 168 // Check database content. 169 stored := rawdb.ReadBlock(db, test.wantHash, 0) 170 if stored.Hash() != test.wantHash { 171 t.Errorf("%s: block in DB has hash %s, want %s", test.name, stored.Hash(), test.wantHash) 172 } 173 } 174 } 175 } 176 177 // TestGenesisHashes checks the congruity of default genesis data to 178 // corresponding hardcoded genesis hash values. 179 func TestGenesisHashes(t *testing.T) { 180 for i, c := range []struct { 181 genesis *Genesis 182 want common.Hash 183 }{ 184 {DefaultGenesisBlock(), params.MainnetGenesisHash}, 185 {DefaultGoerliGenesisBlock(), params.GoerliGenesisHash}, 186 {DefaultSepoliaGenesisBlock(), params.SepoliaGenesisHash}, 187 {DefaultBetaNetGenesisBlock(), params.BetaNetGenesisHash}, 188 } { 189 // Test via MustCommit 190 db := rawdb.NewMemoryDatabase() 191 if have := c.genesis.MustCommit(db, trie.NewDatabase(db, trie.HashDefaults)).Hash(); have != c.want { 192 t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex()) 193 } 194 // Test via ToBlock 195 if have := c.genesis.ToBlock().Hash(); have != c.want { 196 t.Errorf("case: %d a), want: %s, got: %s", i, c.want.Hex(), have.Hex()) 197 } 198 } 199 } 200 201 func TestGenesis_Commit(t *testing.T) { 202 genesis := &Genesis{ 203 BaseFee: big.NewInt(params.InitialBaseFee), 204 Config: params.TestChainConfig, 205 // difficulty is nil 206 } 207 208 db := rawdb.NewMemoryDatabase() 209 genesisBlock := genesis.MustCommit(db, trie.NewDatabase(db, trie.HashDefaults)) 210 211 if genesis.Difficulty != nil { 212 t.Fatalf("assumption wrong") 213 } 214 215 // This value should have been set as default in the ToBlock method. 216 if genesisBlock.Difficulty().Cmp(params.GenesisDifficulty) != 0 { 217 t.Errorf("assumption wrong: want: %d, got: %v", params.GenesisDifficulty, genesisBlock.Difficulty()) 218 } 219 220 // Expect the stored total difficulty to be the difficulty of the genesis block. 221 stored := rawdb.ReadTd(db, genesisBlock.Hash(), genesisBlock.NumberU64()) 222 223 if stored.Cmp(genesisBlock.Difficulty()) != 0 { 224 t.Errorf("inequal difficulty; stored: %v, genesisBlock: %v", stored, genesisBlock.Difficulty()) 225 } 226 } 227 228 func TestReadWriteGenesisAlloc(t *testing.T) { 229 var ( 230 db = rawdb.NewMemoryDatabase() 231 alloc = &GenesisAlloc{ 232 {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, 233 {2}: {Balance: big.NewInt(2), Storage: map[common.Hash]common.Hash{{2}: {2}}}, 234 } 235 hash, _ = alloc.deriveHash() 236 ) 237 blob, _ := json.Marshal(alloc) 238 rawdb.WriteGenesisStateSpec(db, hash, blob) 239 240 var reload GenesisAlloc 241 err := reload.UnmarshalJSON(rawdb.ReadGenesisStateSpec(db, hash)) 242 if err != nil { 243 t.Fatalf("Failed to load genesis state %v", err) 244 } 245 if len(reload) != len(*alloc) { 246 t.Fatal("Unexpected genesis allocation") 247 } 248 for addr, account := range reload { 249 want, ok := (*alloc)[addr] 250 if !ok { 251 t.Fatal("Account is not found") 252 } 253 if !reflect.DeepEqual(want, account) { 254 t.Fatal("Unexpected account") 255 } 256 } 257 } 258 259 func newDbConfig(scheme string) *trie.Config { 260 if scheme == rawdb.HashScheme { 261 return trie.HashDefaults 262 } 263 return &trie.Config{PathDB: pathdb.Defaults} 264 }