github.com/theQRL/go-zond@v0.2.1/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/theQRL/go-zond/common" 29 "github.com/theQRL/go-zond/common/hexutil" 30 "github.com/theQRL/go-zond/common/math" 31 "github.com/theQRL/go-zond/core/rawdb" 32 "github.com/theQRL/go-zond/core/state" 33 "github.com/theQRL/go-zond/core/types" 34 "github.com/theQRL/go-zond/log" 35 "github.com/theQRL/go-zond/params" 36 "github.com/theQRL/go-zond/rlp" 37 "github.com/theQRL/go-zond/trie" 38 "github.com/theQRL/go-zond/zonddb" 39 ) 40 41 //go:generate go run github.com/fjl/gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go 42 //go:generate go run github.com/fjl/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 Timestamp uint64 `json:"timestamp"` 51 ExtraData []byte `json:"extraData"` 52 GasLimit uint64 `json:"gasLimit" gencodec:"required"` 53 Mixhash common.Hash `json:"mixHash"` 54 Coinbase common.Address `json:"coinbase"` 55 Alloc GenesisAlloc `json:"alloc" gencodec:"required"` 56 57 // These fields are used for consensus tests. Please don't use them 58 // in actual genesis blocks. 59 Number uint64 `json:"number"` 60 GasUsed uint64 `json:"gasUsed"` 61 ParentHash common.Hash `json:"parentHash"` 62 BaseFee *big.Int `json:"baseFeePerGas"` 63 } 64 65 func ReadGenesis(db zonddb.Database) (*Genesis, error) { 66 var genesis Genesis 67 stored := rawdb.ReadCanonicalHash(db, 0) 68 if (stored == common.Hash{}) { 69 return nil, fmt.Errorf("invalid genesis hash in database: %x", stored) 70 } 71 blob := rawdb.ReadGenesisStateSpec(db, stored) 72 if blob == nil { 73 return nil, errors.New("genesis state missing from db") 74 } 75 if len(blob) != 0 { 76 if err := genesis.Alloc.UnmarshalJSON(blob); err != nil { 77 return nil, fmt.Errorf("could not unmarshal genesis state json: %s", err) 78 } 79 } 80 genesis.Config = rawdb.ReadChainConfig(db, stored) 81 if genesis.Config == nil { 82 return nil, errors.New("genesis config missing from db") 83 } 84 genesisBlock := rawdb.ReadBlock(db, stored, 0) 85 if genesisBlock == nil { 86 return nil, errors.New("genesis block missing from db") 87 } 88 genesisHeader := genesisBlock.Header() 89 genesis.Timestamp = genesisHeader.Time 90 genesis.ExtraData = genesisHeader.Extra 91 genesis.GasLimit = genesisHeader.GasLimit 92 genesis.Mixhash = genesisHeader.Random 93 genesis.Coinbase = genesisHeader.Coinbase 94 genesis.BaseFee = genesisHeader.BaseFee 95 96 return &genesis, nil 97 } 98 99 // GenesisAlloc specifies the initial state that is part of the genesis block. 100 type GenesisAlloc map[common.Address]GenesisAccount 101 102 func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { 103 m := make(map[common.Address]GenesisAccount) 104 if err := json.Unmarshal(data, &m); err != nil { 105 return err 106 } 107 *ga = make(GenesisAlloc) 108 for addr, a := range m { 109 (*ga)[common.Address(addr)] = a 110 } 111 return nil 112 } 113 114 // deriveHash computes the state root according to the genesis specification. 115 func (ga *GenesisAlloc) deriveHash() (common.Hash, error) { 116 // Create an ephemeral in-memory database for computing hash, 117 // all the derived states will be discarded to not pollute disk. 118 db := state.NewDatabase(rawdb.NewMemoryDatabase()) 119 statedb, err := state.New(types.EmptyRootHash, db, nil) 120 if err != nil { 121 return common.Hash{}, err 122 } 123 for addr, account := range *ga { 124 if account.Balance != nil { 125 statedb.AddBalance(addr, account.Balance) 126 } 127 statedb.SetCode(addr, account.Code) 128 statedb.SetNonce(addr, account.Nonce) 129 for key, value := range account.Storage { 130 statedb.SetState(addr, key, value) 131 } 132 } 133 return statedb.Commit(0, false) 134 } 135 136 // flush is very similar with deriveHash, but the main difference is 137 // all the generated states will be persisted into the given database. 138 // Also, the genesis state specification will be flushed as well. 139 func (ga *GenesisAlloc) flush(db zonddb.Database, triedb *trie.Database, blockhash common.Hash) error { 140 statedb, err := state.New(types.EmptyRootHash, state.NewDatabaseWithNodeDB(db, triedb), nil) 141 if err != nil { 142 return err 143 } 144 for addr, account := range *ga { 145 if account.Balance != nil { 146 statedb.AddBalance(addr, account.Balance) 147 } 148 statedb.SetCode(addr, account.Code) 149 statedb.SetNonce(addr, account.Nonce) 150 for key, value := range account.Storage { 151 statedb.SetState(addr, key, value) 152 } 153 } 154 root, err := statedb.Commit(0, false) 155 if err != nil { 156 return err 157 } 158 // Commit newly generated states into disk if it's not empty. 159 if root != types.EmptyRootHash { 160 if err := triedb.Commit(root, true); err != nil { 161 return err 162 } 163 } 164 // Marshal the genesis state specification and persist. 165 blob, err := json.Marshal(ga) 166 if err != nil { 167 return err 168 } 169 rawdb.WriteGenesisStateSpec(db, blockhash, blob) 170 return nil 171 } 172 173 // CommitGenesisState loads the stored genesis state with the given block 174 // hash and commits it into the provided trie database. 175 func CommitGenesisState(db zonddb.Database, triedb *trie.Database, blockhash common.Hash) error { 176 var alloc GenesisAlloc 177 blob := rawdb.ReadGenesisStateSpec(db, blockhash) 178 if len(blob) != 0 { 179 if err := alloc.UnmarshalJSON(blob); err != nil { 180 return err 181 } 182 } else { 183 // Genesis allocation is missing and there are several possibilities: 184 // the node is legacy which doesn't persist the genesis allocation or 185 // the persisted allocation is just lost. 186 // - supported networks(mainnet, testnets), recover with defined allocations 187 // - private network, can't recover 188 var genesis *Genesis 189 switch blockhash { 190 case params.MainnetGenesisHash: 191 genesis = DefaultGenesisBlock() 192 case params.BetaNetGenesisHash: 193 genesis = DefaultBetaNetGenesisBlock() 194 } 195 if genesis != nil { 196 alloc = genesis.Alloc 197 } else { 198 return errors.New("not found") 199 } 200 } 201 return alloc.flush(db, triedb, blockhash) 202 } 203 204 // GenesisAccount is an account in the state of the genesis block. 205 type GenesisAccount struct { 206 Code []byte `json:"code,omitempty"` 207 Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 208 Balance *big.Int `json:"balance" gencodec:"required"` 209 Nonce uint64 `json:"nonce,omitempty"` 210 Seed []byte `json:"seed,omitempty"` // for tests 211 } 212 213 // field type overrides for gencodec 214 type genesisSpecMarshaling struct { 215 Timestamp math.HexOrDecimal64 216 ExtraData hexutil.Bytes 217 GasLimit math.HexOrDecimal64 218 GasUsed math.HexOrDecimal64 219 Number math.HexOrDecimal64 220 Alloc map[common.Address]GenesisAccount 221 BaseFee *math.HexOrDecimal256 222 } 223 224 type genesisAccountMarshaling struct { 225 Code hexutil.Bytes 226 Balance *math.HexOrDecimal256 227 Nonce math.HexOrDecimal64 228 Storage map[storageJSON]storageJSON 229 PrivateKey hexutil.Bytes 230 } 231 232 // storageJSON represents a 256 bit byte array, but allows less than 256 bits when 233 // unmarshaling from hex. 234 type storageJSON common.Hash 235 236 func (h *storageJSON) UnmarshalText(text []byte) error { 237 text = bytes.TrimPrefix(text, []byte("0x")) 238 if len(text) > 64 { 239 return fmt.Errorf("too many hex characters in storage key/value %q", text) 240 } 241 offset := len(h) - len(text)/2 // pad on the left 242 if _, err := hex.Decode(h[offset:], text); err != nil { 243 return fmt.Errorf("invalid hex storage key/value %q", text) 244 } 245 return nil 246 } 247 248 func (h storageJSON) MarshalText() ([]byte, error) { 249 return hexutil.Bytes(h[:]).MarshalText() 250 } 251 252 // GenesisMismatchError is raised when trying to overwrite an existing 253 // genesis block with an incompatible one. 254 type GenesisMismatchError struct { 255 Stored, New common.Hash 256 } 257 258 func (e *GenesisMismatchError) Error() string { 259 return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) 260 } 261 262 // SetupGenesisBlock writes or updates the genesis block in db. 263 // The block that will be used is: 264 // 265 // genesis == nil genesis != nil 266 // +------------------------------------------ 267 // db has no genesis | main-net default | genesis 268 // db has genesis | from DB | genesis (if compatible) 269 // 270 // The stored chain configuration will be updated if it is compatible (i.e. does not 271 // specify a fork block below the local head block). In case of a conflict, the 272 // error is a *params.ConfigCompatError and the new, unwritten config is returned. 273 // 274 // The returned chain configuration is never nil. 275 func SetupGenesisBlock(db zonddb.Database, triedb *trie.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { 276 return SetupGenesisBlockWithOverride(db, triedb, genesis) 277 } 278 279 func SetupGenesisBlockWithOverride(db zonddb.Database, triedb *trie.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { 280 if genesis != nil && genesis.Config == nil { 281 return params.AllBeaconProtocolChanges, common.Hash{}, errGenesisNoConfig 282 } 283 // Just commit the new block if there is no stored genesis block. 284 stored := rawdb.ReadCanonicalHash(db, 0) 285 if (stored == common.Hash{}) { 286 if genesis == nil { 287 log.Info("Writing default main-net genesis block") 288 genesis = DefaultGenesisBlock() 289 } else { 290 log.Info("Writing custom genesis block") 291 } 292 block, err := genesis.Commit(db, triedb) 293 if err != nil { 294 return genesis.Config, common.Hash{}, err 295 } 296 return genesis.Config, block.Hash(), nil 297 } 298 // The genesis block is present(perhaps in ancient database) while the 299 // state database is not initialized yet. It can happen that the node 300 // is initialized with an external ancient store. Commit genesis state 301 // in this case. 302 header := rawdb.ReadHeader(db, stored, 0) 303 if header.Root != types.EmptyRootHash && !triedb.Initialized(header.Root) { 304 if genesis == nil { 305 genesis = DefaultGenesisBlock() 306 } 307 // Ensure the stored genesis matches with the given one. 308 hash := genesis.ToBlock().Hash() 309 if hash != stored { 310 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 311 } 312 block, err := genesis.Commit(db, triedb) 313 if err != nil { 314 return genesis.Config, hash, err 315 } 316 return genesis.Config, block.Hash(), nil 317 } 318 // Check whether the genesis block is already written. 319 if genesis != nil { 320 hash := genesis.ToBlock().Hash() 321 if hash != stored { 322 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 323 } 324 } 325 // Get the existing chain configuration. 326 newcfg := genesis.configOrDefault(stored) 327 if err := newcfg.CheckConfigForkOrder(); err != nil { 328 return newcfg, common.Hash{}, err 329 } 330 storedcfg := rawdb.ReadChainConfig(db, stored) 331 if storedcfg == nil { 332 log.Warn("Found genesis block without chain config") 333 rawdb.WriteChainConfig(db, stored, newcfg) 334 return newcfg, stored, nil 335 } 336 storedData, _ := json.Marshal(storedcfg) 337 // Special case: if a private network is being used (no genesis and also no 338 // mainnet hash in the database), we must not apply the `configOrDefault` 339 // chain config as that would be AllProtocolChanges (applying any new fork 340 // on top of an existing private network genesis block). In that case, only 341 // apply the overrides. 342 if genesis == nil && stored != params.MainnetGenesisHash { 343 newcfg = storedcfg 344 } 345 // Check config compatibility and write the config. Compatibility errors 346 // are returned to the caller unless we're already at block zero. 347 head := rawdb.ReadHeadHeader(db) 348 if head == nil { 349 return newcfg, stored, errors.New("missing head header") 350 } 351 compatErr := storedcfg.CheckCompatible(newcfg, head.Number.Uint64(), head.Time) 352 if compatErr != nil && ((head.Number.Uint64() != 0 && compatErr.RewindToBlock != 0) || (head.Time != 0 && compatErr.RewindToTime != 0)) { 353 return newcfg, stored, compatErr 354 } 355 // Don't overwrite if the old is identical to the new 356 if newData, _ := json.Marshal(newcfg); !bytes.Equal(storedData, newData) { 357 rawdb.WriteChainConfig(db, stored, newcfg) 358 } 359 return newcfg, stored, nil 360 } 361 362 // LoadChainConfig loads the stored chain config if it is already present in 363 // database, otherwise, return the config in the provided genesis specification. 364 func LoadChainConfig(db zonddb.Database, genesis *Genesis) (*params.ChainConfig, error) { 365 // Load the stored chain config from the database. It can be nil 366 // in case the database is empty. Notably, we only care about the 367 // chain config corresponds to the canonical chain. 368 stored := rawdb.ReadCanonicalHash(db, 0) 369 if stored != (common.Hash{}) { 370 storedcfg := rawdb.ReadChainConfig(db, stored) 371 if storedcfg != nil { 372 return storedcfg, nil 373 } 374 } 375 // Load the config from the provided genesis specification 376 if genesis != nil { 377 // Reject invalid genesis spec without valid chain config 378 if genesis.Config == nil { 379 return nil, errGenesisNoConfig 380 } 381 // If the canonical genesis header is present, but the chain 382 // config is missing(initialize the empty leveldb with an 383 // external ancient chain segment), ensure the provided genesis 384 // is matched. 385 if stored != (common.Hash{}) && genesis.ToBlock().Hash() != stored { 386 return nil, &GenesisMismatchError{stored, genesis.ToBlock().Hash()} 387 } 388 return genesis.Config, nil 389 } 390 // There is no stored chain config and no new config provided, 391 // In this case the default chain config(mainnet) will be used 392 return params.MainnetChainConfig, nil 393 } 394 395 func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { 396 switch { 397 case g != nil: 398 return g.Config 399 case ghash == params.MainnetGenesisHash: 400 return params.MainnetChainConfig 401 default: 402 return params.AllBeaconProtocolChanges 403 } 404 } 405 406 // ToBlock returns the genesis block according to genesis specification. 407 func (g *Genesis) ToBlock() *types.Block { 408 root, err := g.Alloc.deriveHash() 409 if err != nil { 410 panic(err) 411 } 412 head := &types.Header{ 413 Number: new(big.Int).SetUint64(g.Number), 414 Time: g.Timestamp, 415 ParentHash: g.ParentHash, 416 Extra: g.ExtraData, 417 GasLimit: g.GasLimit, 418 GasUsed: g.GasUsed, 419 BaseFee: g.BaseFee, 420 Random: g.Mixhash, 421 Coinbase: g.Coinbase, 422 Root: root, 423 } 424 if g.GasLimit == 0 { 425 head.GasLimit = params.GenesisGasLimit 426 } 427 if g.Config != nil { 428 if g.BaseFee != nil { 429 head.BaseFee = g.BaseFee 430 } else { 431 head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) 432 } 433 } 434 var withdrawals []*types.Withdrawal 435 if conf := g.Config; conf != nil { 436 head.WithdrawalsHash = &types.EmptyWithdrawalsHash 437 withdrawals = make([]*types.Withdrawal, 0) 438 } 439 return types.NewBlock(head, &types.Body{Withdrawals: withdrawals}, nil, trie.NewStackTrie(nil)) 440 } 441 442 // Commit writes the block and state of a genesis specification to the database. 443 // The block is committed as the canonical head block. 444 func (g *Genesis) Commit(db zonddb.Database, triedb *trie.Database) (*types.Block, error) { 445 block := g.ToBlock() 446 if block.Number().Sign() != 0 { 447 return nil, errors.New("can't commit genesis block with number > 0") 448 } 449 config := g.Config 450 if config == nil { 451 config = params.AllBeaconProtocolChanges 452 } 453 if err := config.CheckConfigForkOrder(); err != nil { 454 return nil, err 455 } 456 // All the checks has passed, flush the states derived from the genesis 457 // specification as well as the specification itself into the provided 458 // database. 459 if err := g.Alloc.flush(db, triedb, block.Hash()); err != nil { 460 return nil, err 461 } 462 rawdb.WriteBlock(db, block) 463 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) 464 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 465 rawdb.WriteHeadBlockHash(db, block.Hash()) 466 rawdb.WriteHeadFastBlockHash(db, block.Hash()) 467 rawdb.WriteHeadHeaderHash(db, block.Hash()) 468 rawdb.WriteChainConfig(db, block.Hash(), config) 469 return block, nil 470 } 471 472 // MustCommit writes the genesis block and state to db, panicking on error. 473 // The block is committed as the canonical head block. 474 func (g *Genesis) MustCommit(db zonddb.Database, triedb *trie.Database) *types.Block { 475 block, err := g.Commit(db, triedb) 476 if err != nil { 477 panic(err) 478 } 479 return block 480 } 481 482 // TODO(now.youtrack.cloud/issue/TGZ-16) 483 // DefaultGenesisBlock returns the Zond main net genesis block. 484 func DefaultGenesisBlock() *Genesis { 485 return &Genesis{ 486 Config: params.MainnetChainConfig, 487 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), 488 GasLimit: 5000, 489 Alloc: decodePrealloc(mainnetAllocData), 490 } 491 } 492 493 // DefaultBetaNetGenesisBlock returns the BetaNet network genesis block. 494 func DefaultBetaNetGenesisBlock() *Genesis { 495 return &Genesis{ 496 Config: params.BetaNetChainConfig, 497 ExtraData: []byte("BetaNet, Zond, XMSS, Dilithium!!"), 498 GasLimit: 0x1c9c380, 499 Timestamp: 1705841668, 500 Alloc: decodePreallocWithContractCode(betaNetAllocData), 501 } 502 } 503 504 // DefaultTestnetGenesisBlock returns the BetaNet network genesis block. 505 func DefaultTestnetGenesisBlock() *Genesis { 506 return &Genesis{ 507 Config: params.TestnetChainConfig, 508 ExtraData: hexutil.MustDecode("0x82efec7f3c6d3b266171cb97fd52afced535c77d77979e24add05a6ea0ff3794"), 509 GasLimit: 0x1312d00, 510 Timestamp: 1743071966, 511 Alloc: decodePreallocWithContractCode(testnetAllocData), 512 } 513 } 514 515 // DeveloperGenesisBlock returns the 'gzond --dev' genesis block. 516 func DeveloperGenesisBlock(gasLimit uint64, faucet common.Address) *Genesis { 517 // Override the default period to the user requested one 518 config := *params.AllDevChainProtocolChanges 519 520 // Assemble and return the genesis with the precompiles and faucet pre-funded 521 return &Genesis{ 522 Config: &config, 523 GasLimit: gasLimit, 524 BaseFee: big.NewInt(params.InitialBaseFee), 525 Alloc: map[common.Address]GenesisAccount{ 526 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // DepositRoot 527 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 528 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity 529 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp 530 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd 531 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul 532 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing 533 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 534 }, 535 } 536 } 537 538 func decodePrealloc(data string) GenesisAlloc { 539 var p []struct { 540 Addr *big.Int 541 Balance *big.Int 542 Misc *struct { 543 Nonce uint64 544 Code []byte 545 Slots []struct { 546 Key common.Hash 547 Val common.Hash 548 } 549 } `rlp:"optional"` 550 } 551 if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { 552 panic(err) 553 } 554 ga := make(GenesisAlloc, len(p)) 555 for _, account := range p { 556 acc := GenesisAccount{Balance: account.Balance} 557 if account.Misc != nil { 558 acc.Nonce = account.Misc.Nonce 559 acc.Code = account.Misc.Code 560 561 acc.Storage = make(map[common.Hash]common.Hash) 562 for _, slot := range account.Misc.Slots { 563 acc.Storage[slot.Key] = slot.Val 564 } 565 } 566 ga[common.BigToAddress(account.Addr)] = acc 567 } 568 return ga 569 } 570 571 func decodePreallocWithContractCode(data string) GenesisAlloc { 572 var p []struct { 573 Addr, Balance *big.Int 574 Code []byte 575 } 576 if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { 577 panic(err) 578 } 579 ga := make(GenesisAlloc, len(p)) 580 for _, account := range p { 581 ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance, Code: account.Code} 582 } 583 return ga 584 }