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