github.com/edxfund/validator@v1.8.16-0.20181020093046-c1def72855da/core/genesis.go (about) 1 // Copyright 2014 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 "bytes" 21 "encoding/hex" 22 "encoding/json" 23 "errors" 24 "fmt" 25 "math/big" 26 "strings" 27 28 "github.com/EDXFund/Validator/common" 29 "github.com/EDXFund/Validator/common/hexutil" 30 "github.com/EDXFund/Validator/common/math" 31 "github.com/EDXFund/Validator/core/rawdb" 32 "github.com/EDXFund/Validator/core/state" 33 "github.com/EDXFund/Validator/core/types" 34 "github.com/EDXFund/Validator/ethdb" 35 "github.com/EDXFund/Validator/log" 36 "github.com/EDXFund/Validator/params" 37 "github.com/EDXFund/Validator/rlp" 38 ) 39 40 //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go 41 //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go 42 43 var errGenesisNoConfig = errors.New("genesis has no chain configuration") 44 45 // Genesis specifies the header fields, state of a genesis block. It also defines hard 46 // fork switch-over blocks through the chain configuration. 47 type Genesis struct { 48 Config *params.ChainConfig `json:"config"` 49 Nonce uint64 `json:"nonce"` 50 Timestamp uint64 `json:"timestamp"` 51 ExtraData []byte `json:"extraData"` 52 GasLimit uint64 `json:"gasLimit" gencodec:"required"` 53 Difficulty *big.Int `json:"difficulty" gencodec:"required"` 54 Mixhash common.Hash `json:"mixHash"` 55 Coinbase common.Address `json:"coinbase"` 56 Alloc GenesisAlloc `json:"alloc" gencodec:"required"` 57 58 // These fields are used for consensus tests. Please don't use them 59 // in actual genesis blocks. 60 Number uint64 `json:"number"` 61 GasUsed uint64 `json:"gasUsed"` 62 ParentHash common.Hash `json:"parentHash"` 63 } 64 65 // GenesisAlloc specifies the initial state that is part of the genesis block. 66 type GenesisAlloc map[common.Address]GenesisAccount 67 68 func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { 69 m := make(map[common.UnprefixedAddress]GenesisAccount) 70 if err := json.Unmarshal(data, &m); err != nil { 71 return err 72 } 73 *ga = make(GenesisAlloc) 74 for addr, a := range m { 75 (*ga)[common.Address(addr)] = a 76 } 77 return nil 78 } 79 80 // GenesisAccount is an account in the state of the genesis block. 81 type GenesisAccount struct { 82 Code []byte `json:"code,omitempty"` 83 Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 84 Balance *big.Int `json:"balance" gencodec:"required"` 85 Nonce uint64 `json:"nonce,omitempty"` 86 PrivateKey []byte `json:"secretKey,omitempty"` // for tests 87 } 88 89 // field type overrides for gencodec 90 type genesisSpecMarshaling struct { 91 Nonce math.HexOrDecimal64 92 Timestamp math.HexOrDecimal64 93 ExtraData hexutil.Bytes 94 GasLimit math.HexOrDecimal64 95 GasUsed math.HexOrDecimal64 96 Number math.HexOrDecimal64 97 Difficulty *math.HexOrDecimal256 98 Alloc map[common.UnprefixedAddress]GenesisAccount 99 } 100 101 type genesisAccountMarshaling struct { 102 Code hexutil.Bytes 103 Balance *math.HexOrDecimal256 104 Nonce math.HexOrDecimal64 105 Storage map[storageJSON]storageJSON 106 PrivateKey hexutil.Bytes 107 } 108 109 // storageJSON represents a 256 bit byte array, but allows less than 256 bits when 110 // unmarshaling from hex. 111 type storageJSON common.Hash 112 113 func (h *storageJSON) UnmarshalText(text []byte) error { 114 text = bytes.TrimPrefix(text, []byte("0x")) 115 if len(text) > 64 { 116 return fmt.Errorf("too many hex characters in storage key/value %q", text) 117 } 118 offset := len(h) - len(text)/2 // pad on the left 119 if _, err := hex.Decode(h[offset:], text); err != nil { 120 fmt.Println(err) 121 return fmt.Errorf("invalid hex storage key/value %q", text) 122 } 123 return nil 124 } 125 126 func (h storageJSON) MarshalText() ([]byte, error) { 127 return hexutil.Bytes(h[:]).MarshalText() 128 } 129 130 // GenesisMismatchError is raised when trying to overwrite an existing 131 // genesis block with an incompatible one. 132 type GenesisMismatchError struct { 133 Stored, New common.Hash 134 } 135 136 func (e *GenesisMismatchError) Error() string { 137 return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8]) 138 } 139 140 // SetupGenesisBlock writes or updates the genesis block in db. 141 // The block that will be used is: 142 // 143 // genesis == nil genesis != nil 144 // +------------------------------------------ 145 // db has no genesis | main-net default | genesis 146 // db has genesis | from DB | genesis (if compatible) 147 // 148 // The stored chain configuration will be updated if it is compatible (i.e. does not 149 // specify a fork block below the local head block). In case of a conflict, the 150 // error is a *params.ConfigCompatError and the new, unwritten config is returned. 151 // 152 // The returned chain configuration is never nil. 153 func SetupGenesisBlock(db ethdb.Database, genesis *Genesis, shardId uint16) (*params.ChainConfig, common.Hash, error) { 154 155 if genesis != nil && genesis.Config == nil { 156 return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig 157 } 158 159 // Just commit the new block if there is no stored genesis block. 160 stored := rawdb.ReadCanonicalHash(db, uint16(shardId), 0) 161 if (stored == common.Hash{}) { 162 if genesis == nil { 163 log.Info("Writing default main-net genesis block") 164 genesis = DefaultGenesisBlock() 165 } else { 166 log.Info("Writing custom genesis block") 167 } 168 block, err := genesis.Commit(db) 169 return genesis.Config, block.Hash(), err 170 } 171 172 // Check whether the genesis block is already written. 173 if genesis != nil { 174 hash := genesis.ToBlock(nil).Hash() 175 if hash != stored { 176 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 177 } 178 } 179 180 // Get the existing chain configuration. 181 newcfg := genesis.configOrDefault(stored) 182 storedcfg := rawdb.ReadChainConfig(db, stored) 183 if storedcfg == nil { 184 log.Warn("Found genesis block without chain config") 185 rawdb.WriteChainConfig(db, stored, newcfg) 186 return newcfg, stored, nil 187 } 188 // Special case: don't change the existing config of a non-mainnet chain if no new 189 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 190 // if we just continued here. 191 if genesis == nil && stored != params.MainnetGenesisHash { 192 return storedcfg, stored, nil 193 } 194 195 // Check config compatibility and write the config. Compatibility errors 196 // are returned to the caller unless we're already at block zero. 197 _, height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db, shardId)) 198 if height == nil { 199 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 200 } 201 compatErr := storedcfg.CheckCompatible(newcfg, *height) 202 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 203 return newcfg, stored, compatErr 204 } 205 rawdb.WriteChainConfig(db, stored, newcfg) 206 return newcfg, stored, nil 207 } 208 209 func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { 210 switch { 211 case g != nil: 212 return g.Config 213 case ghash == params.MainnetGenesisHash: 214 return params.MainnetChainConfig 215 case ghash == params.TestnetGenesisHash: 216 return params.TestnetChainConfig 217 default: 218 return params.AllEthashProtocolChanges 219 } 220 } 221 222 // ToBlock creates the genesis block and writes state of a genesis specification 223 // to the given database (or discards it if nil). 224 func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { 225 if db == nil { 226 db = ethdb.NewMemDatabase() 227 } 228 statedb, _ := state.New(common.Hash{}, state.NewDatabase(db)) 229 for addr, account := range g.Alloc { 230 statedb.AddBalance(addr, account.Balance) 231 statedb.SetCode(addr, account.Code) 232 statedb.SetNonce(addr, account.Nonce) 233 for key, value := range account.Storage { 234 statedb.SetState(addr, key, value) 235 } 236 } 237 root := statedb.IntermediateRoot(false) 238 head := &types.Header{ 239 Number: new(big.Int).SetUint64(g.Number), 240 Nonce: types.EncodeNonce(g.Nonce), 241 Time: new(big.Int).SetUint64(g.Timestamp), 242 ParentHash: g.ParentHash, 243 Extra: g.ExtraData, 244 GasLimit: g.GasLimit, 245 GasUsed: g.GasUsed, 246 Difficulty: g.Difficulty, 247 MixDigest: g.Mixhash, 248 Coinbase: g.Coinbase, 249 Root: root, 250 } 251 if g.GasLimit == 0 { 252 head.GasLimit = params.GenesisGasLimit 253 } 254 if g.Difficulty == nil { 255 head.Difficulty = params.GenesisDifficulty 256 } 257 statedb.Commit(false) 258 statedb.Database().TrieDB().Commit(root, true) 259 260 return types.NewBlock(head, nil, nil) 261 } 262 263 // Commit writes the block and state of a genesis specification to the database. 264 // The block is committed as the canonical head block. 265 func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { 266 block := g.ToBlock(db) 267 if block.Number().Sign() != 0 { 268 return nil, fmt.Errorf("can't commit genesis block with number > 0") 269 } 270 shardId := block.Header().ShardId 271 rawdb.WriteTd(db, block.Hash(), shardId, block.NumberU64(), g.Difficulty) 272 rawdb.WriteBlock(db, block) 273 rawdb.WriteReceipts(db, block.Hash(), shardId, block.NumberU64(), nil) 274 rawdb.WriteCanonicalHash(db, block.Hash(), shardId, block.NumberU64()) 275 rawdb.WriteHeadBlockHash(db, block.Hash(), shardId) 276 rawdb.WriteHeadHeaderHash(db, block.Hash(), shardId) 277 278 config := g.Config 279 if config == nil { 280 config = params.AllEthashProtocolChanges 281 } 282 rawdb.WriteChainConfig(db, block.Hash(), config) 283 return block, nil 284 } 285 286 // MustCommit writes the genesis block and state to db, panicking on error. 287 // The block is committed as the canonical head block. 288 func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { 289 block, err := g.Commit(db) 290 if err != nil { 291 panic(err) 292 } 293 return block 294 } 295 296 // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. 297 func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { 298 g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}} 299 return g.MustCommit(db) 300 } 301 302 // DefaultGenesisBlock returns the Ethereum main net genesis block. 303 func DefaultGenesisBlock() *Genesis { 304 return &Genesis{ 305 Config: params.MainnetChainConfig, 306 Nonce: 66, 307 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), 308 GasLimit: 5000, 309 Difficulty: big.NewInt(17179869184), 310 Alloc: decodePrealloc(mainnetAllocData), 311 } 312 } 313 314 // DefaultTestnetGenesisBlock returns the Ropsten network genesis block. 315 func DefaultTestnetGenesisBlock() *Genesis { 316 return &Genesis{ 317 Config: params.TestnetChainConfig, 318 Nonce: 66, 319 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"), 320 GasLimit: 16777216, 321 Difficulty: big.NewInt(1048576), 322 Alloc: decodePrealloc(testnetAllocData), 323 } 324 } 325 326 // DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block. 327 func DefaultRinkebyGenesisBlock() *Genesis { 328 return &Genesis{ 329 Config: params.RinkebyChainConfig, 330 Timestamp: 1492009146, 331 ExtraData: hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), 332 GasLimit: 4700000, 333 Difficulty: big.NewInt(1), 334 Alloc: decodePrealloc(rinkebyAllocData), 335 } 336 } 337 338 // DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must 339 // be seeded with the 340 func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { 341 // Override the default period to the user requested one 342 config := *params.AllCliqueProtocolChanges 343 config.Clique.Period = period 344 345 // Assemble and return the genesis with the precompiles and faucet pre-funded 346 return &Genesis{ 347 Config: &config, 348 ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...), 349 GasLimit: 6283185, 350 Difficulty: big.NewInt(1), 351 Alloc: map[common.Address]GenesisAccount{ 352 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover 353 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 354 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD 355 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity 356 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp 357 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd 358 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul 359 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing 360 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 361 }, 362 } 363 } 364 365 func decodePrealloc(data string) GenesisAlloc { 366 var p []struct{ Addr, Balance *big.Int } 367 if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { 368 panic(err) 369 } 370 ga := make(GenesisAlloc, len(p)) 371 for _, account := range p { 372 ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance} 373 } 374 return ga 375 }