github.com/devfans/go-ethereum@v1.5.10-0.20170326212234-7419d0c38291/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  	"errors"
    21  	"fmt"
    22  	"math/big"
    23  	"strings"
    24  
    25  	"github.com/ethereum/go-ethereum/common"
    26  	"github.com/ethereum/go-ethereum/common/hexutil"
    27  	"github.com/ethereum/go-ethereum/common/math"
    28  	"github.com/ethereum/go-ethereum/core/state"
    29  	"github.com/ethereum/go-ethereum/core/types"
    30  	"github.com/ethereum/go-ethereum/ethdb"
    31  	"github.com/ethereum/go-ethereum/log"
    32  	"github.com/ethereum/go-ethereum/params"
    33  	"github.com/ethereum/go-ethereum/rlp"
    34  )
    35  
    36  //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
    37  //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go
    38  
    39  var errGenesisNoConfig = errors.New("genesis has no chain configuration")
    40  
    41  // Genesis specifies the header fields, state of a genesis block. It also defines hard
    42  // fork switch-over blocks through the chain configuration.
    43  type Genesis struct {
    44  	Config     *params.ChainConfig `json:"config" optional:"true"`
    45  	Nonce      uint64              `json:"nonce" optional:"true"`
    46  	Timestamp  uint64              `json:"timestamp" optional:"true"`
    47  	ParentHash common.Hash         `json:"parentHash" optional:"true"`
    48  	ExtraData  []byte              `json:"extraData" optional:"true"`
    49  	GasLimit   uint64              `json:"gasLimit"`
    50  	Difficulty *big.Int            `json:"difficulty"`
    51  	Mixhash    common.Hash         `json:"mixHash" optional:"true"`
    52  	Coinbase   common.Address      `json:"coinbase" optional:"true"`
    53  	Alloc      GenesisAlloc        `json:"alloc"`
    54  }
    55  
    56  // GenesisAlloc specifies the initial state that is part of the genesis block.
    57  type GenesisAlloc map[common.Address]GenesisAccount
    58  
    59  // GenesisAccount is an account in the state of the genesis block.
    60  type GenesisAccount struct {
    61  	Code    []byte                      `json:"code" optional:"true"`
    62  	Storage map[common.Hash]common.Hash `json:"storage" optional:"true"`
    63  	Balance *big.Int                    `json:"balance"`
    64  	Nonce   uint64                      `json:"nonce" optional:"true"`
    65  }
    66  
    67  // field type overrides for gencodec
    68  type genesisSpecMarshaling struct {
    69  	Nonce      math.HexOrDecimal64
    70  	Timestamp  math.HexOrDecimal64
    71  	ExtraData  hexutil.Bytes
    72  	GasLimit   math.HexOrDecimal64
    73  	Difficulty *math.HexOrDecimal256
    74  	Alloc      map[common.UnprefixedAddress]GenesisAccount
    75  }
    76  type genesisAccountMarshaling struct {
    77  	Code    hexutil.Bytes
    78  	Balance *math.HexOrDecimal256
    79  	Nonce   math.HexOrDecimal64
    80  }
    81  
    82  // GenesisMismatchError is raised when trying to overwrite an existing
    83  // genesis block with an incompatible one.
    84  type GenesisMismatchError struct {
    85  	Stored, New common.Hash
    86  }
    87  
    88  func (e *GenesisMismatchError) Error() string {
    89  	return fmt.Sprintf("wrong genesis block in database (have %x, new %x)", e.Stored[:8], e.New[:8])
    90  }
    91  
    92  // SetupGenesisBlock writes or updates the genesis block in db.
    93  // The block that will be used is:
    94  //
    95  //                          genesis == nil       genesis != nil
    96  //                       +------------------------------------------
    97  //     db has no genesis |  main-net default  |  genesis
    98  //     db has genesis    |  from DB           |  genesis (if compatible)
    99  //
   100  // The stored chain configuration will be updated if it is compatible (i.e. does not
   101  // specify a fork block below the local head block). In case of a conflict, the
   102  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   103  //
   104  // The returned chain configuration is never nil.
   105  func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
   106  	if genesis != nil && genesis.Config == nil {
   107  		return params.AllProtocolChanges, common.Hash{}, errGenesisNoConfig
   108  	}
   109  
   110  	// Just commit the new block if there is no stored genesis block.
   111  	stored := GetCanonicalHash(db, 0)
   112  	if (stored == common.Hash{}) {
   113  		if genesis == nil {
   114  			log.Info("Writing default main-net genesis block")
   115  			genesis = DefaultGenesisBlock()
   116  		} else {
   117  			log.Info("Writing custom genesis block")
   118  		}
   119  		block, err := genesis.Commit(db)
   120  		return genesis.Config, block.Hash(), err
   121  	}
   122  
   123  	// Check whether the genesis block is already written.
   124  	if genesis != nil {
   125  		block, _ := genesis.ToBlock()
   126  		hash := block.Hash()
   127  		if hash != stored {
   128  			return genesis.Config, block.Hash(), &GenesisMismatchError{stored, hash}
   129  		}
   130  	}
   131  
   132  	// Get the existing chain configuration.
   133  	newcfg := genesis.configOrDefault(stored)
   134  	storedcfg, err := GetChainConfig(db, stored)
   135  	if err != nil {
   136  		if err == ChainConfigNotFoundErr {
   137  			// This case happens if a genesis write was interrupted.
   138  			log.Warn("Found genesis block without chain config")
   139  			err = WriteChainConfig(db, stored, newcfg)
   140  		}
   141  		return newcfg, stored, err
   142  	}
   143  	// Special case: don't change the existing config of a non-mainnet chain if no new
   144  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   145  	// if we just continued here.
   146  	if genesis == nil && stored != params.MainNetGenesisHash {
   147  		return storedcfg, stored, nil
   148  	}
   149  
   150  	// Check config compatibility and write the config. Compatibility errors
   151  	// are returned to the caller unless we're already at block zero.
   152  	height := GetBlockNumber(db, GetHeadHeaderHash(db))
   153  	if height == missingNumber {
   154  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   155  	}
   156  	compatErr := storedcfg.CheckCompatible(newcfg, height)
   157  	if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
   158  		return newcfg, stored, compatErr
   159  	}
   160  	return newcfg, stored, WriteChainConfig(db, stored, newcfg)
   161  }
   162  
   163  func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
   164  	switch {
   165  	case g != nil:
   166  		return g.Config
   167  	case ghash == params.MainNetGenesisHash:
   168  		return params.MainnetChainConfig
   169  	case ghash == params.TestNetGenesisHash:
   170  		return params.TestnetChainConfig
   171  	default:
   172  		return params.AllProtocolChanges
   173  	}
   174  }
   175  
   176  // ToBlock creates the block and state of a genesis specification.
   177  func (g *Genesis) ToBlock() (*types.Block, *state.StateDB) {
   178  	db, _ := ethdb.NewMemDatabase()
   179  	statedb, _ := state.New(common.Hash{}, db)
   180  	for addr, account := range g.Alloc {
   181  		statedb.AddBalance(addr, account.Balance)
   182  		statedb.SetCode(addr, account.Code)
   183  		statedb.SetNonce(addr, account.Nonce)
   184  		for key, value := range account.Storage {
   185  			statedb.SetState(addr, key, value)
   186  		}
   187  	}
   188  	root := statedb.IntermediateRoot(false)
   189  	head := &types.Header{
   190  		Nonce:      types.EncodeNonce(g.Nonce),
   191  		Time:       new(big.Int).SetUint64(g.Timestamp),
   192  		ParentHash: g.ParentHash,
   193  		Extra:      g.ExtraData,
   194  		GasLimit:   new(big.Int).SetUint64(g.GasLimit),
   195  		Difficulty: g.Difficulty,
   196  		MixDigest:  g.Mixhash,
   197  		Coinbase:   g.Coinbase,
   198  		Root:       root,
   199  	}
   200  	if g.GasLimit == 0 {
   201  		head.GasLimit = params.GenesisGasLimit
   202  	}
   203  	if g.Difficulty == nil {
   204  		head.Difficulty = params.GenesisDifficulty
   205  	}
   206  	return types.NewBlock(head, nil, nil, nil), statedb
   207  }
   208  
   209  // Commit writes the block and state of a genesis specification to the database.
   210  // The block is committed as the canonical head block.
   211  func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
   212  	block, statedb := g.ToBlock()
   213  	if _, err := statedb.CommitTo(db, false); err != nil {
   214  		return nil, fmt.Errorf("cannot write state: %v", err)
   215  	}
   216  	if err := WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty); err != nil {
   217  		return nil, err
   218  	}
   219  	if err := WriteBlock(db, block); err != nil {
   220  		return nil, err
   221  	}
   222  	if err := WriteBlockReceipts(db, block.Hash(), block.NumberU64(), nil); err != nil {
   223  		return nil, err
   224  	}
   225  	if err := WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
   226  		return nil, err
   227  	}
   228  	if err := WriteHeadBlockHash(db, block.Hash()); err != nil {
   229  		return nil, err
   230  	}
   231  	if err := WriteHeadHeaderHash(db, block.Hash()); err != nil {
   232  		return nil, err
   233  	}
   234  	config := g.Config
   235  	if config == nil {
   236  		config = params.AllProtocolChanges
   237  	}
   238  	return block, WriteChainConfig(db, block.Hash(), config)
   239  }
   240  
   241  // MustCommit writes the genesis block and state to db, panicking on error.
   242  // The block is committed as the canonical head block.
   243  func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
   244  	block, err := g.Commit(db)
   245  	if err != nil {
   246  		panic(err)
   247  	}
   248  	return block
   249  }
   250  
   251  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   252  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
   253  	g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}}
   254  	return g.MustCommit(db)
   255  }
   256  
   257  // DefaultGenesisBlock returns the Ethereum main net genesis block.
   258  func DefaultGenesisBlock() *Genesis {
   259  	return &Genesis{
   260  		Config:     params.MainnetChainConfig,
   261  		Nonce:      66,
   262  		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
   263  		GasLimit:   5000,
   264  		Difficulty: big.NewInt(17179869184),
   265  		Alloc:      decodePrealloc(mainnetAllocData),
   266  	}
   267  }
   268  
   269  // DefaultTestnetGenesisBlock returns the Ropsten network genesis block.
   270  func DefaultTestnetGenesisBlock() *Genesis {
   271  	return &Genesis{
   272  		Config:     params.TestnetChainConfig,
   273  		Nonce:      66,
   274  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
   275  		GasLimit:   16777216,
   276  		Difficulty: big.NewInt(1048576),
   277  		Alloc:      decodePrealloc(testnetAllocData),
   278  	}
   279  }
   280  
   281  // DevGenesisBlock returns the 'geth --dev' genesis block.
   282  func DevGenesisBlock() *Genesis {
   283  	return &Genesis{
   284  		Config:     params.AllProtocolChanges,
   285  		Nonce:      42,
   286  		GasLimit:   4712388,
   287  		Difficulty: big.NewInt(131072),
   288  		Alloc:      decodePrealloc(devAllocData),
   289  	}
   290  }
   291  
   292  func decodePrealloc(data string) GenesisAlloc {
   293  	var p []struct{ Addr, Balance *big.Int }
   294  	if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
   295  		panic(err)
   296  	}
   297  	ga := make(GenesisAlloc, len(p))
   298  	for _, account := range p {
   299  		ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
   300  	}
   301  	return ga
   302  }