github.com/4000d/go-ethereum@v1.8.2-0.20180223170251-423c8bb1d821/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/vm" 28 "github.com/ethereum/go-ethereum/ethdb" 29 "github.com/ethereum/go-ethereum/params" 30 ) 31 32 func TestDefaultGenesisBlock(t *testing.T) { 33 block := DefaultGenesisBlock().ToBlock(nil) 34 if block.Hash() != params.MainnetGenesisHash { 35 t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash) 36 } 37 block = DefaultTestnetGenesisBlock().ToBlock(nil) 38 if block.Hash() != params.TestnetGenesisHash { 39 t.Errorf("wrong testnet genesis hash, got %v, want %v", block.Hash(), params.TestnetGenesisHash) 40 } 41 } 42 43 func TestSetupGenesis(t *testing.T) { 44 var ( 45 customghash = common.HexToHash("0x89c99d90b79719238d2645c7642f2c9295246e80775b38cfd162b696817fbd50") 46 customg = Genesis{ 47 Config: ¶ms.ChainConfig{HomesteadBlock: big.NewInt(3)}, 48 Alloc: GenesisAlloc{ 49 {1}: {Balance: big.NewInt(1), Storage: map[common.Hash]common.Hash{{1}: {1}}}, 50 }, 51 } 52 oldcustomg = customg 53 ) 54 oldcustomg.Config = ¶ms.ChainConfig{HomesteadBlock: big.NewInt(2)} 55 tests := []struct { 56 name string 57 fn func(ethdb.Database) (*params.ChainConfig, common.Hash, error) 58 wantConfig *params.ChainConfig 59 wantHash common.Hash 60 wantErr error 61 }{ 62 { 63 name: "genesis without ChainConfig", 64 fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { 65 return SetupGenesisBlock(db, new(Genesis)) 66 }, 67 wantErr: errGenesisNoConfig, 68 wantConfig: params.AllEthashProtocolChanges, 69 }, 70 { 71 name: "no block in DB, genesis == nil", 72 fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { 73 return SetupGenesisBlock(db, nil) 74 }, 75 wantHash: params.MainnetGenesisHash, 76 wantConfig: params.MainnetChainConfig, 77 }, 78 { 79 name: "mainnet block in DB, genesis == nil", 80 fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { 81 DefaultGenesisBlock().MustCommit(db) 82 return SetupGenesisBlock(db, nil) 83 }, 84 wantHash: params.MainnetGenesisHash, 85 wantConfig: params.MainnetChainConfig, 86 }, 87 { 88 name: "custom block in DB, genesis == nil", 89 fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { 90 customg.MustCommit(db) 91 return SetupGenesisBlock(db, nil) 92 }, 93 wantHash: customghash, 94 wantConfig: customg.Config, 95 }, 96 { 97 name: "custom block in DB, genesis == testnet", 98 fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { 99 customg.MustCommit(db) 100 return SetupGenesisBlock(db, DefaultTestnetGenesisBlock()) 101 }, 102 wantErr: &GenesisMismatchError{Stored: customghash, New: params.TestnetGenesisHash}, 103 wantHash: params.TestnetGenesisHash, 104 wantConfig: params.TestnetChainConfig, 105 }, 106 { 107 name: "compatible config in DB", 108 fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { 109 oldcustomg.MustCommit(db) 110 return SetupGenesisBlock(db, &customg) 111 }, 112 wantHash: customghash, 113 wantConfig: customg.Config, 114 }, 115 { 116 name: "incompatible config in DB", 117 fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, error) { 118 // Commit the 'old' genesis block with Homestead transition at #2. 119 // Advance to block #4, past the homestead transition block of customg. 120 genesis := oldcustomg.MustCommit(db) 121 122 bc, _ := NewBlockChain(db, nil, oldcustomg.Config, ethash.NewFullFaker(), vm.Config{}) 123 defer bc.Stop() 124 125 blocks, _ := GenerateChain(oldcustomg.Config, genesis, ethash.NewFaker(), db, 4, nil) 126 bc.InsertChain(blocks) 127 bc.CurrentBlock() 128 // This should return a compatibility error. 129 return SetupGenesisBlock(db, &customg) 130 }, 131 wantHash: customghash, 132 wantConfig: customg.Config, 133 wantErr: ¶ms.ConfigCompatError{ 134 What: "Homestead fork block", 135 StoredConfig: big.NewInt(2), 136 NewConfig: big.NewInt(3), 137 RewindTo: 1, 138 }, 139 }, 140 } 141 142 for _, test := range tests { 143 db, _ := ethdb.NewMemDatabase() 144 config, hash, err := test.fn(db) 145 // Check the return values. 146 if !reflect.DeepEqual(err, test.wantErr) { 147 spew := spew.ConfigState{DisablePointerAddresses: true, DisableCapacities: true} 148 t.Errorf("%s: returned error %#v, want %#v", test.name, spew.NewFormatter(err), spew.NewFormatter(test.wantErr)) 149 } 150 if !reflect.DeepEqual(config, test.wantConfig) { 151 t.Errorf("%s:\nreturned %v\nwant %v", test.name, config, test.wantConfig) 152 } 153 if hash != test.wantHash { 154 t.Errorf("%s: returned hash %s, want %s", test.name, hash.Hex(), test.wantHash.Hex()) 155 } else if err == nil { 156 // Check database content. 157 stored := GetBlock(db, test.wantHash, 0) 158 if stored.Hash() != test.wantHash { 159 t.Errorf("%s: block in DB has hash %s, want %s", test.name, stored.Hash(), test.wantHash) 160 } 161 } 162 } 163 }