gitlab.com/yannislg/go-pulse@v0.0.0-20210722055913-a3e24e95638d/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/ethereum/go-ethereum/common"
    29  	"github.com/ethereum/go-ethereum/common/hexutil"
    30  	"github.com/ethereum/go-ethereum/common/math"
    31  	"github.com/ethereum/go-ethereum/core/rawdb"
    32  	"github.com/ethereum/go-ethereum/core/state"
    33  	"github.com/ethereum/go-ethereum/core/systemcontracts"
    34  	"github.com/ethereum/go-ethereum/core/types"
    35  	"github.com/ethereum/go-ethereum/crypto"
    36  	"github.com/ethereum/go-ethereum/ethdb"
    37  	"github.com/ethereum/go-ethereum/log"
    38  	"github.com/ethereum/go-ethereum/params"
    39  	"github.com/ethereum/go-ethereum/rlp"
    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  }
    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  		(*ga)[common.Address(addr)] = a
    78  	}
    79  	return nil
    80  }
    81  
    82  // GenesisAccount is an account in the state of the genesis block.
    83  type GenesisAccount struct {
    84  	Code       []byte                      `json:"code,omitempty"`
    85  	Storage    map[common.Hash]common.Hash `json:"storage,omitempty"`
    86  	Balance    *big.Int                    `json:"balance" gencodec:"required"`
    87  	Nonce      uint64                      `json:"nonce,omitempty"`
    88  	PrivateKey []byte                      `json:"secretKey,omitempty"` // for tests
    89  }
    90  
    91  // field type overrides for gencodec
    92  type genesisSpecMarshaling struct {
    93  	Nonce      math.HexOrDecimal64
    94  	Timestamp  math.HexOrDecimal64
    95  	ExtraData  hexutil.Bytes
    96  	GasLimit   math.HexOrDecimal64
    97  	GasUsed    math.HexOrDecimal64
    98  	Number     math.HexOrDecimal64
    99  	Difficulty *math.HexOrDecimal256
   100  	Alloc      map[common.UnprefixedAddress]GenesisAccount
   101  }
   102  
   103  type genesisAccountMarshaling struct {
   104  	Code       hexutil.Bytes
   105  	Balance    *math.HexOrDecimal256
   106  	Nonce      math.HexOrDecimal64
   107  	Storage    map[storageJSON]storageJSON
   108  	PrivateKey hexutil.Bytes
   109  }
   110  
   111  // storageJSON represents a 256 bit byte array, but allows less than 256 bits when
   112  // unmarshaling from hex.
   113  type storageJSON common.Hash
   114  
   115  func (h *storageJSON) UnmarshalText(text []byte) error {
   116  	text = bytes.TrimPrefix(text, []byte("0x"))
   117  	if len(text) > 64 {
   118  		return fmt.Errorf("too many hex characters in storage key/value %q", text)
   119  	}
   120  	offset := len(h) - len(text)/2 // pad on the left
   121  	if _, err := hex.Decode(h[offset:], text); err != nil {
   122  		fmt.Println(err)
   123  		return fmt.Errorf("invalid hex storage key/value %q", text)
   124  	}
   125  	return nil
   126  }
   127  
   128  func (h storageJSON) MarshalText() ([]byte, error) {
   129  	return hexutil.Bytes(h[:]).MarshalText()
   130  }
   131  
   132  // GenesisMismatchError is raised when trying to overwrite an existing
   133  // genesis block with an incompatible one.
   134  type GenesisMismatchError struct {
   135  	Stored, New common.Hash
   136  }
   137  
   138  func (e *GenesisMismatchError) Error() string {
   139  	return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New)
   140  }
   141  
   142  // SetupGenesisBlock writes or updates the genesis block in db.
   143  // The block that will be used is:
   144  //
   145  //                          genesis == nil       genesis != nil
   146  //                       +------------------------------------------
   147  //     db has no genesis |  main-net default  |  genesis
   148  //     db has genesis    |  from DB           |  genesis (if compatible)
   149  //
   150  // The stored chain configuration will be updated if it is compatible (i.e. does not
   151  // specify a fork block below the local head block). In case of a conflict, the
   152  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   153  //
   154  // The returned chain configuration is never nil.
   155  func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
   156  	return SetupGenesisBlockWithOverride(db, genesis, nil, nil)
   157  }
   158  
   159  func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis, overrideIstanbul, overrideMuirGlacier *big.Int) (*params.ChainConfig, common.Hash, error) {
   160  	if genesis != nil && genesis.Config == nil {
   161  		return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
   162  	}
   163  	// Just commit the new block if there is no stored genesis block.
   164  	stored := rawdb.ReadCanonicalHash(db, 0)
   165  	systemcontracts.GenesisHash = stored
   166  	if (stored == common.Hash{}) {
   167  		if genesis == nil {
   168  			log.Info("Writing default main-net genesis block")
   169  			genesis = DefaultGenesisBlock()
   170  		} else {
   171  			log.Info("Writing custom genesis block")
   172  		}
   173  		block, err := genesis.Commit(db)
   174  		if err != nil {
   175  			return genesis.Config, common.Hash{}, err
   176  		}
   177  		return genesis.Config, block.Hash(), nil
   178  	}
   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.NewDatabaseWithCache(db, 0), 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  
   199  	// Check whether the genesis block is already written.
   200  	if genesis != nil {
   201  		hash := genesis.ToBlock(nil).Hash()
   202  		if hash != stored {
   203  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   204  		}
   205  	}
   206  
   207  	// Get the existing chain configuration.
   208  	newcfg := genesis.configOrDefault(stored)
   209  	if overrideIstanbul != nil {
   210  		newcfg.IstanbulBlock = overrideIstanbul
   211  	}
   212  	if overrideMuirGlacier != nil {
   213  		newcfg.MuirGlacierBlock = overrideMuirGlacier
   214  	}
   215  	if err := newcfg.CheckConfigForkOrder(); err != nil {
   216  		return newcfg, common.Hash{}, err
   217  	}
   218  	storedcfg := rawdb.ReadChainConfig(db, stored)
   219  	if storedcfg == nil {
   220  		log.Warn("Found genesis block without chain config")
   221  		rawdb.WriteChainConfig(db, stored, newcfg)
   222  		return newcfg, stored, nil
   223  	}
   224  	// Special case: don't change the existing config of a non-mainnet chain if no new
   225  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   226  	// if we just continued here.
   227  	// The full node of two BSC testnets may run without genesis file after been inited.
   228  	if genesis == nil && stored != params.MainnetGenesisHash &&
   229  		stored != params.ChapelGenesisHash && stored != params.RialtoGenesisHash && stored != params.BSCGenesisHash {
   230  		return storedcfg, stored, nil
   231  	}
   232  
   233  	// Check config compatibility and write the config. Compatibility errors
   234  	// are returned to the caller unless we're already at block zero.
   235  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
   236  	if height == nil {
   237  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   238  	}
   239  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   240  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   241  		return newcfg, stored, compatErr
   242  	}
   243  	rawdb.WriteChainConfig(db, stored, newcfg)
   244  	return newcfg, stored, nil
   245  }
   246  
   247  func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
   248  	switch {
   249  	case g != nil:
   250  		return g.Config
   251  	case ghash == params.MainnetGenesisHash:
   252  		return params.MainnetChainConfig
   253  	case ghash == params.RopstenGenesisHash:
   254  		return params.RopstenChainConfig
   255  	case ghash == params.RinkebyGenesisHash:
   256  		return params.RinkebyChainConfig
   257  	case ghash == params.GoerliGenesisHash:
   258  		return params.GoerliChainConfig
   259  	case ghash == params.BSCGenesisHash:
   260  		return params.BSCChainConfig
   261  	case ghash == params.ChapelGenesisHash:
   262  		return params.ChapelChainConfig
   263  	case ghash == params.RialtoGenesisHash:
   264  		return params.RialtoChainConfig
   265  	default:
   266  		return params.AllEthashProtocolChanges
   267  	}
   268  }
   269  
   270  // ToBlock creates the genesis block and writes state of a genesis specification
   271  // to the given database (or discards it if nil).
   272  func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
   273  	if db == nil {
   274  		db = rawdb.NewMemoryDatabase()
   275  	}
   276  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil)
   277  	for addr, account := range g.Alloc {
   278  		statedb.AddBalance(addr, account.Balance)
   279  		statedb.SetCode(addr, account.Code)
   280  		statedb.SetNonce(addr, account.Nonce)
   281  		for key, value := range account.Storage {
   282  			statedb.SetState(addr, key, value)
   283  		}
   284  	}
   285  	root := statedb.IntermediateRoot(false)
   286  	head := &types.Header{
   287  		Number:     new(big.Int).SetUint64(g.Number),
   288  		Nonce:      types.EncodeNonce(g.Nonce),
   289  		Time:       g.Timestamp,
   290  		ParentHash: g.ParentHash,
   291  		Extra:      g.ExtraData,
   292  		GasLimit:   g.GasLimit,
   293  		GasUsed:    g.GasUsed,
   294  		Difficulty: g.Difficulty,
   295  		MixDigest:  g.Mixhash,
   296  		Coinbase:   g.Coinbase,
   297  		Root:       root,
   298  	}
   299  	if g.GasLimit == 0 {
   300  		head.GasLimit = params.GenesisGasLimit
   301  	}
   302  	if g.Difficulty == nil {
   303  		head.Difficulty = params.GenesisDifficulty
   304  	}
   305  	statedb.Commit(false)
   306  	statedb.Database().TrieDB().Commit(root, true)
   307  
   308  	return types.NewBlock(head, nil, nil, nil)
   309  }
   310  
   311  // Commit writes the block and state of a genesis specification to the database.
   312  // The block is committed as the canonical head block.
   313  func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
   314  	block := g.ToBlock(db)
   315  	if block.Number().Sign() != 0 {
   316  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   317  	}
   318  	config := g.Config
   319  	if config == nil {
   320  		config = params.AllEthashProtocolChanges
   321  	}
   322  	if err := config.CheckConfigForkOrder(); err != nil {
   323  		return nil, err
   324  	}
   325  	rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
   326  	rawdb.WriteBlock(db, block)
   327  	rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
   328  	rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
   329  	rawdb.WriteHeadBlockHash(db, block.Hash())
   330  	rawdb.WriteHeadFastBlockHash(db, block.Hash())
   331  	rawdb.WriteHeadHeaderHash(db, block.Hash())
   332  	rawdb.WriteChainConfig(db, block.Hash(), config)
   333  	return block, nil
   334  }
   335  
   336  // MustCommit writes the genesis block and state to db, panicking on error.
   337  // The block is committed as the canonical head block.
   338  func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
   339  	block, err := g.Commit(db)
   340  	if err != nil {
   341  		panic(err)
   342  	}
   343  	return block
   344  }
   345  
   346  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   347  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
   348  	g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}}
   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.Period = period
   405  
   406  	// Assemble and return the genesis with the precompiles and faucet pre-funded
   407  	return &Genesis{
   408  		Config:     &config,
   409  		ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
   410  		GasLimit:   6283185,
   411  		Difficulty: big.NewInt(1),
   412  		Alloc: map[common.Address]GenesisAccount{
   413  			common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
   414  			common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
   415  			common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
   416  			common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
   417  			common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
   418  			common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
   419  			common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
   420  			common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
   421  			faucet:                           {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
   422  		},
   423  	}
   424  }
   425  
   426  func decodePrealloc(data string) GenesisAlloc {
   427  	var p []struct{ Addr, Balance *big.Int }
   428  	if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
   429  		panic(err)
   430  	}
   431  	ga := make(GenesisAlloc, len(p))
   432  	for _, account := range p {
   433  		ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
   434  	}
   435  	return ga
   436  }