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