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