github.com/dominant-strategies/go-quai@v0.28.2/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 "io/ioutil" 26 "math/big" 27 "os" 28 29 "github.com/dominant-strategies/go-quai/common" 30 "github.com/dominant-strategies/go-quai/common/hexutil" 31 "github.com/dominant-strategies/go-quai/common/math" 32 "github.com/dominant-strategies/go-quai/core/rawdb" 33 "github.com/dominant-strategies/go-quai/core/state" 34 "github.com/dominant-strategies/go-quai/core/types" 35 "github.com/dominant-strategies/go-quai/crypto" 36 "github.com/dominant-strategies/go-quai/ethdb" 37 "github.com/dominant-strategies/go-quai/log" 38 "github.com/dominant-strategies/go-quai/params" 39 "github.com/dominant-strategies/go-quai/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 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 BaseFee *big.Int `json:"baseFeePerGas"` 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 internal := common.InternalAddress(addr) 78 (*ga)[common.NewAddressFromData(&internal)] = a 79 } 80 return nil 81 } 82 83 // GenesisAccount is an account in the state of the genesis block. 84 type GenesisAccount struct { 85 Code []byte `json:"code,omitempty"` 86 Storage map[common.Hash]common.Hash `json:"storage,omitempty"` 87 Balance *big.Int `json:"balance" gencodec:"required"` 88 Nonce uint64 `json:"nonce,omitempty"` 89 PrivateKey []byte `json:"secretKey,omitempty"` // for tests 90 } 91 92 // field type overrides for gencodec 93 type genesisSpecMarshaling struct { 94 Nonce math.HexOrDecimal64 95 Timestamp math.HexOrDecimal64 96 ExtraData hexutil.Bytes 97 GasLimit math.HexOrDecimal64 98 GasUsed math.HexOrDecimal64 99 Number math.HexOrDecimal64 100 Difficulty *math.HexOrDecimal256 101 BaseFee *math.HexOrDecimal256 102 Alloc map[common.UnprefixedAddress]GenesisAccount 103 } 104 105 type genesisAccountMarshaling struct { 106 Code hexutil.Bytes 107 Balance *math.HexOrDecimal256 108 Nonce math.HexOrDecimal64 109 Storage map[storageJSON]storageJSON 110 PrivateKey hexutil.Bytes 111 } 112 113 // storageJSON represents a 256 bit byte array, but allows less than 256 bits when 114 // unmarshaling from hex. 115 type storageJSON common.Hash 116 117 func (h *storageJSON) UnmarshalText(text []byte) error { 118 text = bytes.TrimPrefix(text, []byte("0x")) 119 if len(text) > 64 { 120 return fmt.Errorf("too many hex characters in storage key/value %q", text) 121 } 122 offset := len(h) - len(text)/2 // pad on the left 123 if _, err := hex.Decode(h[offset:], text); err != nil { 124 fmt.Println(err) 125 return fmt.Errorf("invalid hex storage key/value %q", text) 126 } 127 return nil 128 } 129 130 func (h storageJSON) MarshalText() ([]byte, error) { 131 return hexutil.Bytes(h[:]).MarshalText() 132 } 133 134 // GenesisMismatchError is raised when trying to overwrite an existing 135 // genesis block with an incompatible one. 136 type GenesisMismatchError struct { 137 Stored, New common.Hash 138 } 139 140 func (e *GenesisMismatchError) Error() string { 141 return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New) 142 } 143 144 // SetupGenesisBlock writes or updates the genesis block in db. 145 // The block that will be used is: 146 // 147 // genesis == nil genesis != nil 148 // +------------------------------------------ 149 // db has no genesis | main-net default | genesis 150 // db has genesis | from DB | genesis (if compatible) 151 // 152 // The stored chain configuration will be updated if it is compatible (i.e. does not 153 // specify a fork block below the local head block). In case of a conflict, the 154 // error is a *params.ConfigCompatError and the new, unwritten config is returned. 155 // 156 // The returned chain configuration is never nil. 157 func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { 158 return SetupGenesisBlockWithOverride(db, genesis) 159 } 160 161 func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) { 162 if genesis != nil && genesis.Config == nil { 163 return params.AllProgpowProtocolChanges, common.Hash{}, errGenesisNoConfig 164 } 165 // Just commit the new block if there is no stored genesis block. 166 stored := rawdb.ReadCanonicalHash(db, 0) 167 if (stored == common.Hash{}) { 168 if genesis == nil { 169 log.Info("Writing default main-net genesis block") 170 genesis = DefaultGenesisBlock() 171 } else { 172 log.Info("Writing custom genesis block") 173 } 174 block, err := genesis.Commit(db) 175 if err != nil { 176 return genesis.Config, common.Hash{}, err 177 } 178 return genesis.Config, block.Hash(), nil 179 } 180 // We have the genesis block in database(perhaps in ancient database) 181 // but the corresponding state is missing. 182 header := rawdb.ReadHeader(db, stored, 0) 183 if _, err := state.New(header.Root(), state.NewDatabaseWithConfig(db, nil), nil); err != nil { 184 if genesis == nil { 185 genesis = DefaultGenesisBlock() 186 } 187 // Ensure the stored genesis matches with the given one. 188 hash := genesis.ToBlock(nil).Hash() 189 if hash != stored { 190 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 191 } 192 block, err := genesis.Commit(db) 193 if err != nil { 194 return genesis.Config, hash, err 195 } 196 return genesis.Config, block.Hash(), nil 197 } 198 // Check whether the genesis block is already written. 199 if genesis != nil { 200 hash := genesis.ToBlock(nil).Hash() 201 if hash != stored { 202 return genesis.Config, hash, &GenesisMismatchError{stored, hash} 203 } 204 } 205 // Get the existing chain configuration. 206 newcfg := genesis.configOrDefault(stored) 207 storedcfg := rawdb.ReadChainConfig(db, stored) 208 if storedcfg == nil { 209 log.Warn("Found genesis block without chain config") 210 rawdb.WriteChainConfig(db, stored, newcfg) 211 return newcfg, stored, nil 212 } 213 // Special case: don't change the existing config of a non-mainnet chain if no new 214 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 215 // if we just continued here. 216 if genesis == nil && stored != params.ProgpowColosseumGenesisHash { 217 return storedcfg, stored, nil 218 } 219 // Check config compatibility and write the config. Compatibility errors 220 // are returned to the caller unless we're already at block zero. 221 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 222 if height == nil { 223 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 224 } 225 226 rawdb.WriteChainConfig(db, stored, newcfg) 227 return newcfg, stored, nil 228 } 229 230 func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { 231 switch { 232 case g != nil: 233 return g.Config 234 case ghash == params.ProgpowColosseumGenesisHash: 235 return params.ProgpowColosseumChainConfig 236 case ghash == params.ProgpowGardenGenesisHash: 237 return params.ProgpowGardenChainConfig 238 case ghash == params.ProgpowOrchardGenesisHash: 239 return params.ProgpowOrchardChainConfig 240 case ghash == params.ProgpowLighthouseGenesisHash: 241 return params.ProgpowLighthouseChainConfig 242 case ghash == params.ProgpowLocalGenesisHash: 243 return params.ProgpowLocalChainConfig 244 // Blake3 chain configs 245 case ghash == params.Blake3PowColosseumGenesisHash: 246 return params.Blake3PowColosseumChainConfig 247 case ghash == params.Blake3PowGardenGenesisHash: 248 return params.Blake3PowGardenChainConfig 249 case ghash == params.Blake3PowOrchardGenesisHash: 250 return params.Blake3PowOrchardChainConfig 251 case ghash == params.Blake3PowLighthouseGenesisHash: 252 return params.Blake3PowLighthouseChainConfig 253 case ghash == params.Blake3PowLocalGenesisHash: 254 return params.Blake3PowLocalChainConfig 255 256 default: 257 return params.AllProgpowProtocolChanges 258 } 259 } 260 261 // ToBlock creates the genesis block and writes state of a genesis specification 262 // to the given database (or discards it if nil). 263 func (g *Genesis) ToBlock(db ethdb.Database) *types.Block { 264 head := types.EmptyHeader() 265 head.SetNonce(types.EncodeNonce(g.Nonce)) 266 head.SetTime(g.Timestamp) 267 head.SetExtra(g.ExtraData) 268 head.SetDifficulty(g.Difficulty) 269 head.SetCoinbase(common.ZeroAddr) 270 head.SetGasLimit(g.GasLimit) 271 head.SetGasUsed(0) 272 head.SetBaseFee(new(big.Int).SetUint64(params.InitialBaseFee)) 273 if g.GasLimit == 0 { 274 head.SetGasLimit(params.GenesisGasLimit) 275 } 276 for i := 0; i < common.HierarchyDepth; i++ { 277 head.SetNumber(big.NewInt(0), i) 278 head.SetParentHash(common.Hash{}, i) 279 } 280 281 return types.NewBlock(head, nil, nil, nil, nil, nil, trie.NewStackTrie(nil)) 282 } 283 284 // Commit writes the block and state of a genesis specification to the database. 285 // The block is committed as the canonical head block. 286 func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { 287 block := g.ToBlock(db) 288 if block.Number().Sign() != 0 { 289 return nil, fmt.Errorf("can't commit genesis block with number > 0") 290 } 291 config := g.Config 292 if config == nil { 293 config = params.AllProgpowProtocolChanges 294 } 295 rawdb.WriteTermini(db, block.Hash(), types.EmptyTermini()) 296 rawdb.WriteBlock(db, block) 297 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) 298 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 299 rawdb.WriteHeadBlockHash(db, block.Hash()) 300 rawdb.WriteHeadHeaderHash(db, block.Hash()) 301 rawdb.WriteChainConfig(db, block.Hash(), config) 302 return block, nil 303 } 304 305 // MustCommit writes the genesis block and state to db, panicking on error. 306 // The block is committed as the canonical head block. 307 func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { 308 block, err := g.Commit(db) 309 if err != nil { 310 panic(err) 311 } 312 return block 313 } 314 315 // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. 316 func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { 317 g := Genesis{ 318 BaseFee: big.NewInt(params.InitialBaseFee), 319 } 320 return g.MustCommit(db) 321 } 322 323 // DefaultGenesisBlock returns the Latest default Genesis block. 324 // Currently it returns the DefaultColosseumGenesisBlock. 325 func DefaultGenesisBlock() *Genesis { 326 return DefaultColosseumGenesisBlock("progpow") 327 } 328 329 // DefaultColosseumGenesisBlock returns the Quai Colosseum testnet genesis block. 330 func DefaultColosseumGenesisBlock(consensusEngine string) *Genesis { 331 if consensusEngine == "blake3" { 332 return &Genesis{ 333 Config: params.Blake3PowColosseumChainConfig, 334 Nonce: 66, 335 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"), 336 GasLimit: 5000000, 337 Difficulty: big.NewInt(2000000), 338 } 339 } 340 return &Genesis{ 341 Config: params.ProgpowColosseumChainConfig, 342 Nonce: 66, 343 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"), 344 GasLimit: 5000000, 345 Difficulty: big.NewInt(1000000000), 346 } 347 } 348 349 // DefaultGardenGenesisBlock returns the Garden testnet genesis block. 350 func DefaultGardenGenesisBlock(consensusEngine string) *Genesis { 351 if consensusEngine == "blake3" { 352 return &Genesis{ 353 Config: params.Blake3PowGardenChainConfig, 354 Nonce: 66, 355 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), 356 GasLimit: 40000000, 357 Difficulty: big.NewInt(4000000), 358 } 359 } 360 return &Genesis{ 361 Config: params.ProgpowGardenChainConfig, 362 Nonce: 0, 363 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353539"), 364 GasLimit: 5000000, 365 Difficulty: big.NewInt(300000000), 366 } 367 } 368 369 // DefaultOrchardGenesisBlock returns the Orchard testnet genesis block. 370 func DefaultOrchardGenesisBlock(consensusEngine string) *Genesis { 371 if consensusEngine == "blake3" { 372 return &Genesis{ 373 Config: params.Blake3PowOrchardChainConfig, 374 Nonce: 66, 375 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fc"), 376 GasLimit: 5000000, 377 Difficulty: big.NewInt(4000000), 378 } 379 } 380 return &Genesis{ 381 Config: params.ProgpowOrchardChainConfig, 382 Nonce: 0, 383 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353536"), 384 GasLimit: 5000000, 385 Difficulty: big.NewInt(300000000), 386 } 387 } 388 389 // DefaultLighthouseGenesisBlock returns the Lighthouse testnet genesis block. 390 func DefaultLighthouseGenesisBlock(consensusEngine string) *Genesis { 391 if consensusEngine == "blake3" { 392 return &Genesis{ 393 Config: params.Blake3PowLighthouseChainConfig, 394 Nonce: 66, 395 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"), 396 GasLimit: 40000000, 397 Difficulty: big.NewInt(4000000), 398 } 399 } 400 return &Genesis{ 401 Config: params.ProgpowLighthouseChainConfig, 402 Nonce: 0, 403 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353537"), 404 GasLimit: 5000000, 405 Difficulty: big.NewInt(300000000), 406 } 407 } 408 409 // DefaultLocalGenesisBlock returns the Local testnet genesis block. 410 func DefaultLocalGenesisBlock(consensusEngine string) *Genesis { 411 if consensusEngine == "blake3" { 412 return &Genesis{ 413 Config: params.Blake3PowLocalChainConfig, 414 Nonce: 66, 415 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"), 416 GasLimit: 5000000, 417 Difficulty: big.NewInt(300000), 418 } 419 } 420 return &Genesis{ 421 Config: params.ProgpowLocalChainConfig, 422 Nonce: 0, 423 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"), 424 GasLimit: 5000000, 425 Difficulty: big.NewInt(1000), 426 } 427 } 428 429 // DeveloperGenesisBlock returns the 'quai --dev' genesis block. 430 func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { 431 // Override the default period to the user requested one 432 config := *params.AllProgpowProtocolChanges 433 // Assemble and return the genesis with the precompiles and faucet pre-funded 434 return &Genesis{ 435 Config: &config, 436 ExtraData: append(append(make([]byte, 32), faucet.Bytes()[:]...), make([]byte, crypto.SignatureLength)...), 437 GasLimit: 0x47b760, 438 BaseFee: big.NewInt(params.InitialBaseFee), 439 Difficulty: big.NewInt(1), 440 } 441 } 442 443 func ReadGenesisAlloc(filename string) map[string]GenesisAccount { 444 jsonFile, err := os.Open(filename) 445 if err != nil { 446 log.Error(err.Error()) 447 return nil 448 } 449 defer jsonFile.Close() 450 // Read the file contents 451 byteValue, err := ioutil.ReadAll(jsonFile) 452 if err != nil { 453 log.Error(err.Error()) 454 return nil 455 } 456 457 // Parse the JSON data 458 var data map[string]GenesisAccount 459 err = json.Unmarshal(byteValue, &data) 460 if err != nil { 461 log.Error(err.Error()) 462 return nil 463 } 464 465 // Use the parsed data 466 return data 467 }