github.com/juliankolbe/go-ethereum@v1.9.992/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/juliankolbe/go-ethereum/common"
    29  	"github.com/juliankolbe/go-ethereum/common/hexutil"
    30  	"github.com/juliankolbe/go-ethereum/common/math"
    31  	"github.com/juliankolbe/go-ethereum/core/rawdb"
    32  	"github.com/juliankolbe/go-ethereum/core/state"
    33  	"github.com/juliankolbe/go-ethereum/core/types"
    34  	"github.com/juliankolbe/go-ethereum/crypto"
    35  	"github.com/juliankolbe/go-ethereum/ethdb"
    36  	"github.com/juliankolbe/go-ethereum/log"
    37  	"github.com/juliankolbe/go-ethereum/params"
    38  	"github.com/juliankolbe/go-ethereum/rlp"
    39  	"github.com/juliankolbe/go-ethereum/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  }
    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  	if genesis != nil && genesis.Config == nil {
   157  		return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
   158  	}
   159  	// Just commit the new block if there is no stored genesis block.
   160  	stored := rawdb.ReadCanonicalHash(db, 0)
   161  	if (stored == common.Hash{}) {
   162  		if genesis == nil {
   163  			log.Info("Writing default main-net genesis block")
   164  			genesis = DefaultGenesisBlock()
   165  		} else {
   166  			log.Info("Writing custom genesis block")
   167  		}
   168  		block, err := genesis.Commit(db)
   169  		if err != nil {
   170  			return genesis.Config, common.Hash{}, err
   171  		}
   172  		return genesis.Config, block.Hash(), nil
   173  	}
   174  	// We have the genesis block in database(perhaps in ancient database)
   175  	// but the corresponding state is missing.
   176  	header := rawdb.ReadHeader(db, stored, 0)
   177  	if _, err := state.New(header.Root, state.NewDatabaseWithConfig(db, nil), nil); err != nil {
   178  		if genesis == nil {
   179  			genesis = DefaultGenesisBlock()
   180  		}
   181  		// Ensure the stored genesis matches with the given one.
   182  		hash := genesis.ToBlock(nil).Hash()
   183  		if hash != stored {
   184  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   185  		}
   186  		block, err := genesis.Commit(db)
   187  		if err != nil {
   188  			return genesis.Config, hash, err
   189  		}
   190  		return genesis.Config, block.Hash(), nil
   191  	}
   192  	// Check whether the genesis block is already written.
   193  	if genesis != nil {
   194  		hash := genesis.ToBlock(nil).Hash()
   195  		if hash != stored {
   196  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   197  		}
   198  	}
   199  	// Get the existing chain configuration.
   200  	newcfg := genesis.configOrDefault(stored)
   201  	if err := newcfg.CheckConfigForkOrder(); err != nil {
   202  		return newcfg, common.Hash{}, err
   203  	}
   204  	storedcfg := rawdb.ReadChainConfig(db, stored)
   205  	if storedcfg == nil {
   206  		log.Warn("Found genesis block without chain config")
   207  		rawdb.WriteChainConfig(db, stored, newcfg)
   208  		return newcfg, stored, nil
   209  	}
   210  	// Special case: don't change the existing config of a non-mainnet chain if no new
   211  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   212  	// if we just continued here.
   213  	if genesis == nil && stored != params.MainnetGenesisHash {
   214  		return storedcfg, stored, nil
   215  	}
   216  	// Check config compatibility and write the config. Compatibility errors
   217  	// are returned to the caller unless we're already at block zero.
   218  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
   219  	if height == nil {
   220  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   221  	}
   222  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   223  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   224  		return newcfg, stored, compatErr
   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.MainnetGenesisHash:
   235  		return params.MainnetChainConfig
   236  	case ghash == params.RopstenGenesisHash:
   237  		return params.RopstenChainConfig
   238  	case ghash == params.RinkebyGenesisHash:
   239  		return params.RinkebyChainConfig
   240  	case ghash == params.GoerliGenesisHash:
   241  		return params.GoerliChainConfig
   242  	case ghash == params.YoloV3GenesisHash:
   243  		return params.YoloV3ChainConfig
   244  	default:
   245  		return params.AllEthashProtocolChanges
   246  	}
   247  }
   248  
   249  // ToBlock creates the genesis block and writes state of a genesis specification
   250  // to the given database (or discards it if nil).
   251  func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
   252  	if db == nil {
   253  		db = rawdb.NewMemoryDatabase()
   254  	}
   255  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db), nil)
   256  	for addr, account := range g.Alloc {
   257  		statedb.AddBalance(addr, account.Balance)
   258  		statedb.SetCode(addr, account.Code)
   259  		statedb.SetNonce(addr, account.Nonce)
   260  		for key, value := range account.Storage {
   261  			statedb.SetState(addr, key, value)
   262  		}
   263  	}
   264  	root := statedb.IntermediateRoot(false)
   265  	head := &types.Header{
   266  		Number:     new(big.Int).SetUint64(g.Number),
   267  		Nonce:      types.EncodeNonce(g.Nonce),
   268  		Time:       g.Timestamp,
   269  		ParentHash: g.ParentHash,
   270  		Extra:      g.ExtraData,
   271  		GasLimit:   g.GasLimit,
   272  		GasUsed:    g.GasUsed,
   273  		Difficulty: g.Difficulty,
   274  		MixDigest:  g.Mixhash,
   275  		Coinbase:   g.Coinbase,
   276  		Root:       root,
   277  	}
   278  	if g.GasLimit == 0 {
   279  		head.GasLimit = params.GenesisGasLimit
   280  	}
   281  	if g.Difficulty == nil {
   282  		head.Difficulty = params.GenesisDifficulty
   283  	}
   284  	statedb.Commit(false)
   285  	statedb.Database().TrieDB().Commit(root, true, nil)
   286  
   287  	return types.NewBlock(head, nil, nil, nil, trie.NewStackTrie(nil))
   288  }
   289  
   290  // Commit writes the block and state of a genesis specification to the database.
   291  // The block is committed as the canonical head block.
   292  func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
   293  	block := g.ToBlock(db)
   294  	if block.Number().Sign() != 0 {
   295  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   296  	}
   297  	config := g.Config
   298  	if config == nil {
   299  		config = params.AllEthashProtocolChanges
   300  	}
   301  	if err := config.CheckConfigForkOrder(); err != nil {
   302  		return nil, err
   303  	}
   304  	rawdb.WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty)
   305  	rawdb.WriteBlock(db, block)
   306  	rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
   307  	rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
   308  	rawdb.WriteHeadBlockHash(db, block.Hash())
   309  	rawdb.WriteHeadFastBlockHash(db, block.Hash())
   310  	rawdb.WriteHeadHeaderHash(db, block.Hash())
   311  	rawdb.WriteChainConfig(db, block.Hash(), config)
   312  	return block, nil
   313  }
   314  
   315  // MustCommit writes the genesis block and state to db, panicking on error.
   316  // The block is committed as the canonical head block.
   317  func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
   318  	block, err := g.Commit(db)
   319  	if err != nil {
   320  		panic(err)
   321  	}
   322  	return block
   323  }
   324  
   325  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   326  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
   327  	g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}}
   328  	return g.MustCommit(db)
   329  }
   330  
   331  // DefaultGenesisBlock returns the Ethereum main net genesis block.
   332  func DefaultGenesisBlock() *Genesis {
   333  	return &Genesis{
   334  		Config:     params.MainnetChainConfig,
   335  		Nonce:      66,
   336  		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
   337  		GasLimit:   5000,
   338  		Difficulty: big.NewInt(17179869184),
   339  		Alloc:      decodePrealloc(mainnetAllocData),
   340  	}
   341  }
   342  
   343  // DefaultRopstenGenesisBlock returns the Ropsten network genesis block.
   344  func DefaultRopstenGenesisBlock() *Genesis {
   345  	return &Genesis{
   346  		Config:     params.RopstenChainConfig,
   347  		Nonce:      66,
   348  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
   349  		GasLimit:   16777216,
   350  		Difficulty: big.NewInt(1048576),
   351  		Alloc:      decodePrealloc(ropstenAllocData),
   352  	}
   353  }
   354  
   355  // DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block.
   356  func DefaultRinkebyGenesisBlock() *Genesis {
   357  	return &Genesis{
   358  		Config:     params.RinkebyChainConfig,
   359  		Timestamp:  1492009146,
   360  		ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   361  		GasLimit:   4700000,
   362  		Difficulty: big.NewInt(1),
   363  		Alloc:      decodePrealloc(rinkebyAllocData),
   364  	}
   365  }
   366  
   367  // DefaultGoerliGenesisBlock returns the Görli network genesis block.
   368  func DefaultGoerliGenesisBlock() *Genesis {
   369  	return &Genesis{
   370  		Config:     params.GoerliChainConfig,
   371  		Timestamp:  1548854791,
   372  		ExtraData:  hexutil.MustDecode("0x22466c6578692069732061207468696e6722202d204166726900000000000000e0a2bd4258d2768837baa26a28fe71dc079f84c70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   373  		GasLimit:   10485760,
   374  		Difficulty: big.NewInt(1),
   375  		Alloc:      decodePrealloc(goerliAllocData),
   376  	}
   377  }
   378  
   379  func DefaultYoloV3GenesisBlock() *Genesis {
   380  	// Full genesis: https://gist.github.com/holiman/c6ed9269dce28304ad176314caa75e97
   381  	return &Genesis{
   382  		Config:     params.YoloV3ChainConfig,
   383  		Timestamp:  0x6027dd2e,
   384  		ExtraData:  hexutil.MustDecode("0x00000000000000000000000000000000000000000000000000000000000000001041afbcb359d5a8dc58c15b2ff51354ff8a217d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   385  		GasLimit:   0x47b760,
   386  		Difficulty: big.NewInt(1),
   387  		Alloc:      decodePrealloc(yoloV3AllocData),
   388  	}
   389  }
   390  
   391  // DeveloperGenesisBlock returns the 'geth --dev' genesis block.
   392  func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
   393  	// Override the default period to the user requested one
   394  	config := *params.AllCliqueProtocolChanges
   395  	config.Clique.Period = period
   396  
   397  	// Assemble and return the genesis with the precompiles and faucet pre-funded
   398  	return &Genesis{
   399  		Config:     &config,
   400  		ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, crypto.SignatureLength)...),
   401  		GasLimit:   11500000,
   402  		Difficulty: big.NewInt(1),
   403  		Alloc: map[common.Address]GenesisAccount{
   404  			common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
   405  			common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
   406  			common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
   407  			common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
   408  			common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
   409  			common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
   410  			common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
   411  			common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
   412  			common.BytesToAddress([]byte{9}): {Balance: big.NewInt(1)}, // BLAKE2b
   413  			faucet:                           {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
   414  		},
   415  	}
   416  }
   417  
   418  func decodePrealloc(data string) GenesisAlloc {
   419  	var p []struct{ Addr, Balance *big.Int }
   420  	if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
   421  		panic(err)
   422  	}
   423  	ga := make(GenesisAlloc, len(p))
   424  	for _, account := range p {
   425  		ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
   426  	}
   427  	return ga
   428  }