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