github.com/aidoskuneen/adk-node@v0.0.0-20220315131952-2e32567cb7f4/core/genesis.go (about) 1 // Copyright 2021 The adkgo Authors 2 // This file is part of the adkgo library (adapted for adkgo from go--ethereum v1.10.8). 3 // 4 // the adkgo 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 adkgo 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 adkgo 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/aidoskuneen/adk-node/common" 29 "github.com/aidoskuneen/adk-node/common/hexutil" 30 "github.com/aidoskuneen/adk-node/common/math" 31 "github.com/aidoskuneen/adk-node/core/rawdb" 32 "github.com/aidoskuneen/adk-node/core/state" 33 "github.com/aidoskuneen/adk-node/core/types" 34 "github.com/aidoskuneen/adk-node/crypto" 35 "github.com/aidoskuneen/adk-node/ethdb" 36 "github.com/aidoskuneen/adk-node/log" 37 "github.com/aidoskuneen/adk-node/params" 38 "github.com/aidoskuneen/adk-node/rlp" 39 "github.com/aidoskuneen/adk-node/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 BaseFee *big.Int `json:"baseFeePerGas"` 66 } 67 68 // GenesisAlloc specifies the initial state that is part of the genesis block. 69 type GenesisAlloc map[common.Address]GenesisAccount 70 71 func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error { 72 m := make(map[common.UnprefixedAddress]GenesisAccount) 73 if err := json.Unmarshal(data, &m); err != nil { 74 return err 75 } 76 *ga = make(GenesisAlloc) 77 for addr, a := range m { 78 (*ga)[common.Address(addr)] = 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, nil) 159 } 160 161 func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideLondon *big.Int) (*params.ChainConfig, common.Hash, error) { 162 if genesis != nil && genesis.Config == nil { 163 return params.AllEthashProtocolChanges, 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 if overrideLondon != nil { 208 newcfg.LondonBlock = overrideLondon 209 } 210 if err := newcfg.CheckConfigForkOrder(); err != nil { 211 return newcfg, common.Hash{}, err 212 } 213 storedcfg := rawdb.ReadChainConfig(db, stored) 214 if storedcfg == nil { 215 log.Warn("Found genesis block without chain config") 216 rawdb.WriteChainConfig(db, stored, newcfg) 217 return newcfg, stored, nil 218 } 219 // Special case: don't change the existing config of a non-mainnet chain if no new 220 // config is supplied. These chains would get AllProtocolChanges (and a compat error) 221 // if we just continued here. 222 if genesis == nil && stored != params.MainnetGenesisHash { 223 return storedcfg, stored, nil 224 } 225 // Check config compatibility and write the config. Compatibility errors 226 // are returned to the caller unless we're already at block zero. 227 height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db)) 228 if height == nil { 229 return newcfg, stored, fmt.Errorf("missing block number for head header hash") 230 } 231 compatErr := storedcfg.CheckCompatible(newcfg, *height) 232 if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 { 233 return newcfg, stored, compatErr 234 } 235 rawdb.WriteChainConfig(db, stored, newcfg) 236 return newcfg, stored, nil 237 } 238 239 func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig { 240 switch { 241 case g != nil: 242 return g.Config 243 case ghash == params.MainnetGenesisHash: 244 return params.MainnetChainConfig 245 case ghash == params.RopstenGenesisHash: 246 return params.RopstenChainConfig 247 case ghash == params.RinkebyGenesisHash: 248 return params.RinkebyChainConfig 249 case ghash == params.GoerliGenesisHash: 250 return params.GoerliChainConfig 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, err := state.New(common.Hash{}, state.NewDatabase(db), nil) 263 if err != nil { 264 panic(err) 265 } 266 for addr, account := range g.Alloc { 267 statedb.AddBalance(addr, account.Balance) 268 statedb.SetCode(addr, account.Code) 269 statedb.SetNonce(addr, account.Nonce) 270 for key, value := range account.Storage { 271 statedb.SetState(addr, key, value) 272 } 273 } 274 root := statedb.IntermediateRoot(false) 275 head := &types.Header{ 276 Number: new(big.Int).SetUint64(g.Number), 277 Nonce: types.EncodeNonce(g.Nonce), 278 Time: g.Timestamp, 279 ParentHash: g.ParentHash, 280 Extra: g.ExtraData, 281 GasLimit: g.GasLimit, 282 GasUsed: g.GasUsed, 283 BaseFee: g.BaseFee, 284 Difficulty: g.Difficulty, 285 MixDigest: g.Mixhash, 286 Coinbase: g.Coinbase, 287 Root: root, 288 } 289 if g.GasLimit == 0 { 290 head.GasLimit = params.GenesisGasLimit 291 } 292 if g.Difficulty == nil { 293 head.Difficulty = params.GenesisDifficulty 294 } 295 if g.Config != nil && g.Config.IsLondon(common.Big0) { 296 if g.BaseFee != nil { 297 head.BaseFee = g.BaseFee 298 } else { 299 head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee) 300 } 301 } 302 statedb.Commit(false) 303 statedb.Database().TrieDB().Commit(root, true, nil) 304 305 return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil)) 306 } 307 308 // Commit writes the block and state of a genesis specification to the database. 309 // The block is committed as the canonical head block. 310 func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) { 311 block := g.ToBlock(db) 312 if block.Number().Sign() != 0 { 313 return nil, fmt.Errorf("can't commit genesis block with number > 0") 314 } 315 config := g.Config 316 if config == nil { 317 config = params.AllEthashProtocolChanges 318 } 319 if err := config.CheckConfigForkOrder(); err != nil { 320 return nil, err 321 } 322 rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty) 323 rawdb.WriteBlock(db, block) 324 rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil) 325 rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64()) 326 rawdb.WriteHeadBlockHash(db, block.Hash()) 327 rawdb.WriteHeadFastBlockHash(db, block.Hash()) 328 rawdb.WriteHeadHeaderHash(db, block.Hash()) 329 rawdb.WriteChainConfig(db, block.Hash(), config) 330 return block, nil 331 } 332 333 // MustCommit writes the genesis block and state to db, panicking on error. 334 // The block is committed as the canonical head block. 335 func (g *Genesis) MustCommit(db ethdb.Database) *types.Block { 336 block, err := g.Commit(db) 337 if err != nil { 338 panic(err) 339 } 340 return block 341 } 342 343 // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance. 344 func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { 345 g := Genesis{ 346 Alloc: GenesisAlloc{addr: {Balance: balance}}, 347 BaseFee: big.NewInt(params.InitialBaseFee), 348 } 349 return g.MustCommit(db) 350 } 351 352 // DefaultGenesisBlock returns the Ethereum main net genesis block. 353 func DefaultGenesisBlock() *Genesis { 354 return &Genesis{ 355 Config: params.MainnetChainConfig, 356 Nonce: 66, 357 ExtraData: hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"), 358 GasLimit: 5000, 359 Difficulty: big.NewInt(17179869184), 360 Alloc: decodePrealloc(mainnetAllocData), 361 } 362 } 363 364 // DefaultRopstenGenesisBlock returns the Ropsten network genesis block. 365 func DefaultRopstenGenesisBlock() *Genesis { 366 return &Genesis{ 367 Config: params.RopstenChainConfig, 368 Nonce: 66, 369 ExtraData: hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"), 370 GasLimit: 16777216, 371 Difficulty: big.NewInt(1048576), 372 Alloc: decodePrealloc(ropstenAllocData), 373 } 374 } 375 376 // DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block. 377 func DefaultRinkebyGenesisBlock() *Genesis { 378 return &Genesis{ 379 Config: params.RinkebyChainConfig, 380 Timestamp: 1492009146, 381 ExtraData: hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), 382 GasLimit: 4700000, 383 Difficulty: big.NewInt(1), 384 Alloc: decodePrealloc(rinkebyAllocData), 385 } 386 } 387 388 // DefaultGoerliGenesisBlock returns the Görli network genesis block. 389 func DefaultGoerliGenesisBlock() *Genesis { 390 return &Genesis{ 391 Config: params.GoerliChainConfig, 392 Timestamp: 1548854791, 393 ExtraData: hexutil.MustDecode("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"), 394 GasLimit: 10485760, 395 Difficulty: big.NewInt(1), 396 Alloc: decodePrealloc(goerliAllocData), 397 } 398 } 399 400 // DeveloperGenesisBlock returns the 'geth --dev' genesis block. 401 func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis { 402 // Override the default period to the user requested one 403 config := *params.AllCliqueProtocolChanges 404 config.Clique = ¶ms.CliqueConfig{ 405 Period: period, 406 Epoch: config.Clique.Epoch, 407 } 408 409 // Assemble and return the genesis with the precompiles and faucet pre-funded 410 return &Genesis{ 411 Config: &config, 412 ExtraData: append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...), 413 GasLimit: 11500000, 414 BaseFee: big.NewInt(params.InitialBaseFee), 415 Difficulty: big.NewInt(1), 416 Alloc: map[common.Address]GenesisAccount{ 417 common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover 418 common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256 419 common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD 420 common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity 421 common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp 422 common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd 423 common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul 424 common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing 425 common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b 426 faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))}, 427 }, 428 } 429 } 430 431 func decodePrealloc(data string) GenesisAlloc { 432 var p []struct{ Addr, Balance *big.Int } 433 if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil { 434 panic(err) 435 } 436 ga := make(GenesisAlloc, len(p)) 437 for _, account := range p { 438 ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance} 439 } 440 return ga 441 }