github.com/Evanesco-Labs/go-evanesco@v1.0.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/Evanesco-Labs/go-evanesco/common"
    29  	"github.com/Evanesco-Labs/go-evanesco/common/hexutil"
    30  	"github.com/Evanesco-Labs/go-evanesco/common/math"
    31  	"github.com/Evanesco-Labs/go-evanesco/core/rawdb"
    32  	"github.com/Evanesco-Labs/go-evanesco/core/state"
    33  	"github.com/Evanesco-Labs/go-evanesco/core/types"
    34  	"github.com/Evanesco-Labs/go-evanesco/crypto"
    35  	"github.com/Evanesco-Labs/go-evanesco/ethdb"
    36  	"github.com/Evanesco-Labs/go-evanesco/log"
    37  	"github.com/Evanesco-Labs/go-evanesco/params"
    38  	"github.com/Evanesco-Labs/go-evanesco/rlp"
    39  	"github.com/Evanesco-Labs/go-evanesco/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  	case ghash == params.CalaverasGenesisHash:
   252  		return params.CalaverasChainConfig
   253  	default:
   254  		return params.AllEthashProtocolChanges
   255  	}
   256  }
   257  
   258  // ToBlock creates the genesis block and writes state of a genesis specification
   259  // to the given database (or discards it if nil).
   260  func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
   261  	if db == nil {
   262  		db = rawdb.NewMemoryDatabase()
   263  	}
   264  	statedb, err := state.New(common.Hash{}, state.NewDatabase(db), nil)
   265  	if err != nil {
   266  		panic(err)
   267  	}
   268  	for addr, account := range g.Alloc {
   269  		statedb.AddBalance(addr, account.Balance)
   270  		statedb.SetCode(addr, account.Code)
   271  		statedb.SetNonce(addr, account.Nonce)
   272  		for key, value := range account.Storage {
   273  			statedb.SetState(addr, key, value)
   274  		}
   275  	}
   276  	root := statedb.IntermediateRoot(false)
   277  	head := &types.Header{
   278  		Number:     new(big.Int).SetUint64(g.Number),
   279  		Nonce:      types.EncodeNonce(g.Nonce),
   280  		Time:       g.Timestamp,
   281  		ParentHash: g.ParentHash,
   282  		Extra:      g.ExtraData,
   283  		GasLimit:   g.GasLimit,
   284  		GasUsed:    g.GasUsed,
   285  		BaseFee:    g.BaseFee,
   286  		Difficulty: g.Difficulty,
   287  		MixDigest:  g.Mixhash,
   288  		Coinbase:   g.Coinbase,
   289  		Root:       root,
   290  	}
   291  	if g.GasLimit == 0 {
   292  		head.GasLimit = params.GenesisGasLimit
   293  	}
   294  	if g.Difficulty == nil {
   295  		head.Difficulty = params.GenesisDifficulty
   296  	}
   297  	if g.Config != nil && g.Config.IsLondon(common.Big0) {
   298  		if g.BaseFee != nil {
   299  			head.BaseFee = g.BaseFee
   300  		} else {
   301  			head.BaseFee = new(big.Int).SetUint64(params.InitialBaseFee)
   302  		}
   303  	}
   304  	statedb.Commit(false)
   305  	statedb.Database().TrieDB().Commit(root, true, nil)
   306  
   307  	return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil))
   308  }
   309  
   310  // Commit writes the block and state of a genesis specification to the database.
   311  // The block is committed as the canonical head block.
   312  func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
   313  	block := g.ToBlock(db)
   314  	if block.Number().Sign() != 0 {
   315  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   316  	}
   317  	config := g.Config
   318  	if config == nil {
   319  		config = params.AllEthashProtocolChanges
   320  	}
   321  	if err := config.CheckConfigForkOrder(); err != nil {
   322  		return nil, err
   323  	}
   324  	rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
   325  	rawdb.WriteBlock(db, block)
   326  	rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
   327  	rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
   328  	rawdb.WriteHeadBlockHash(db, block.Hash())
   329  	rawdb.WriteHeadFastBlockHash(db, block.Hash())
   330  	rawdb.WriteHeadHeaderHash(db, block.Hash())
   331  	rawdb.WriteChainConfig(db, block.Hash(), config)
   332  	return block, nil
   333  }
   334  
   335  // MustCommit writes the genesis block and state to db, panicking on error.
   336  // The block is committed as the canonical head block.
   337  func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
   338  	block, err := g.Commit(db)
   339  	if err != nil {
   340  		panic(err)
   341  	}
   342  	return block
   343  }
   344  
   345  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   346  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
   347  	g := Genesis{
   348  		Alloc:   GenesisAlloc{addr: {Balance: balance}},
   349  		BaseFee: big.NewInt(params.InitialBaseFee),
   350  	}
   351  	return g.MustCommit(db)
   352  }
   353  
   354  // DefaultGenesisBlock returns the Ethereum main net genesis block.
   355  func DefaultGenesisBlock() *Genesis {
   356  	return &Genesis{
   357  		Config:     params.MainnetChainConfig,
   358  		Nonce:      66,
   359  		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
   360  		GasLimit:   5000,
   361  		Difficulty: big.NewInt(17179869184),
   362  		Alloc:      decodePrealloc(mainnetAllocData),
   363  	}
   364  }
   365  
   366  // DefaultRopstenGenesisBlock returns the Ropsten network genesis block.
   367  func DefaultRopstenGenesisBlock() *Genesis {
   368  	return &Genesis{
   369  		Config:     params.RopstenChainConfig,
   370  		Nonce:      66,
   371  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
   372  		GasLimit:   16777216,
   373  		Difficulty: big.NewInt(1048576),
   374  		Alloc:      decodePrealloc(ropstenAllocData),
   375  	}
   376  }
   377  
   378  // DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block.
   379  func DefaultRinkebyGenesisBlock() *Genesis {
   380  	return &Genesis{
   381  		Config:     params.RinkebyChainConfig,
   382  		Timestamp:  1492009146,
   383  		ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   384  		GasLimit:   4700000,
   385  		Difficulty: big.NewInt(1),
   386  		Alloc:      decodePrealloc(rinkebyAllocData),
   387  	}
   388  }
   389  
   390  // DefaultGoerliGenesisBlock returns the Görli network genesis block.
   391  func DefaultGoerliGenesisBlock() *Genesis {
   392  	return &Genesis{
   393  		Config:     params.GoerliChainConfig,
   394  		Timestamp:  1548854791,
   395  		ExtraData:  hexutil.MustDecode("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   396  		GasLimit:   10485760,
   397  		Difficulty: big.NewInt(1),
   398  		Alloc:      decodePrealloc(goerliAllocData),
   399  	}
   400  }
   401  
   402  func DefaultCalaverasGenesisBlock() *Genesis {
   403  	// Full genesis: https://gist.github.com/holiman/c6ed9269dce28304ad176314caa75e97
   404  	return &Genesis{
   405  		Config:     params.CalaverasChainConfig,
   406  		Timestamp:  0x60b3877f,
   407  		ExtraData:  hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000005211cea3870c7ba7c6c44b185e62eecdb864cd8c560228ce57d31efbf64c200b2c200aacec78cf17a7148e784fe95a7a750335f8b9572ee28d72e7650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   408  		GasLimit:   0x47b760,
   409  		Difficulty: big.NewInt(1),
   410  		Alloc:      decodePrealloc(calaverasAllocData),
   411  	}
   412  }
   413  
   414  // DeveloperGenesisBlock returns the 'geth --dev' genesis block.
   415  func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
   416  	// Override the default period to the user requested one
   417  	config := *params.AllCliqueProtocolChanges
   418  	config.Clique = &params.CliqueConfig{
   419  		Period: period,
   420  		Epoch:  config.Clique.Epoch,
   421  	}
   422  
   423  	// Assemble and return the genesis with the precompiles and faucet pre-funded
   424  	return &Genesis{
   425  		Config:     &config,
   426  		ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
   427  		GasLimit:   11500000,
   428  		BaseFee:    big.NewInt(params.InitialBaseFee),
   429  		Difficulty: big.NewInt(1),
   430  		Alloc: map[common.Address]GenesisAccount{
   431  			common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
   432  			common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
   433  			common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
   434  			common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
   435  			common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
   436  			common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
   437  			common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
   438  			common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
   439  			common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b
   440  			faucet:                           {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
   441  		},
   442  	}
   443  }
   444  
   445  func decodePrealloc(data string) GenesisAlloc {
   446  	var p []struct{ Addr, Balance *big.Int }
   447  	if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
   448  		panic(err)
   449  	}
   450  	ga := make(GenesisAlloc, len(p))
   451  	for _, account := range p {
   452  		ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
   453  	}
   454  	return ga
   455  }