github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/core/genesis.go (about)

     1  // Copyright 2018 Wanchain Foundation Ltd
     2  // Copyright 2014 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package core
    19  
    20  import (
    21  	"bytes"
    22  	"encoding/hex"
    23  	"encoding/json"
    24  	"errors"
    25  	"fmt"
    26  	"math/big"
    27  	"strings"
    28  
    29  	"github.com/wanchain/go-wanchain/common"
    30  	"github.com/wanchain/go-wanchain/common/hexutil"
    31  	"github.com/wanchain/go-wanchain/common/math"
    32  	"github.com/wanchain/go-wanchain/core/state"
    33  	"github.com/wanchain/go-wanchain/core/types"
    34  	"github.com/wanchain/go-wanchain/crypto"
    35  	"github.com/wanchain/go-wanchain/ethdb"
    36  	"github.com/wanchain/go-wanchain/log"
    37  	"github.com/wanchain/go-wanchain/params"
    38  	"github.com/wanchain/go-wanchain/rlp"
    39  )
    40  
    41  //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
    42  //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go
    43  
    44  var errGenesisNoConfig = errors.New("genesis has no chain configuration")
    45  
    46  // Genesis specifies the header fields, state of a genesis block. It also defines hard
    47  // fork switch-over blocks through the chain configuration.
    48  type Genesis struct {
    49  	Config     *params.ChainConfig `json:"config"`
    50  	Nonce      uint64              `json:"nonce"`
    51  	Timestamp  uint64              `json:"timestamp"`
    52  	ExtraData  []byte              `json:"extraData"`
    53  	GasLimit   uint64              `json:"gasLimit"   gencodec:"required"`
    54  	Difficulty *big.Int            `json:"difficulty" gencodec:"required"`
    55  	Mixhash    common.Hash         `json:"mixHash"`
    56  	Coinbase   common.Address      `json:"coinbase"`
    57  	Alloc      GenesisAlloc        `json:"alloc"      gencodec:"required"`
    58  
    59  	// These fields are used for consensus tests. Please don't use them
    60  	// in actual genesis blocks.
    61  	Number     uint64      `json:"number"`
    62  	GasUsed    uint64      `json:"gasUsed"`
    63  	ParentHash common.Hash `json:"parentHash"`
    64  }
    65  
    66  // GenesisAlloc specifies the initial state that is part of the genesis block.
    67  type GenesisAlloc map[common.Address]GenesisAccount
    68  
    69  func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
    70  	m := make(map[common.UnprefixedAddress]GenesisAccount)
    71  	if err := json.Unmarshal(data, &m); err != nil {
    72  		return err
    73  	}
    74  	*ga = make(GenesisAlloc)
    75  	for addr, a := range m {
    76  		(*ga)[common.Address(addr)] = a
    77  	}
    78  	return nil
    79  }
    80  
    81  // GenesisAccount is an account in the state of the genesis block.
    82  type GenesisAccount struct {
    83  	Code       []byte                      `json:"code,omitempty"`
    84  	Storage    map[common.Hash]common.Hash `json:"storage,omitempty"`
    85  	Balance    *big.Int                    `json:"balance" gencodec:"required"`
    86  	Nonce      uint64                      `json:"nonce,omitempty"`
    87  	PrivateKey []byte                      `json:"secretKey,omitempty"` // for tests
    88  }
    89  
    90  // field type overrides for gencodec
    91  type genesisSpecMarshaling struct {
    92  	Nonce      math.HexOrDecimal64
    93  	Timestamp  math.HexOrDecimal64
    94  	ExtraData  hexutil.Bytes
    95  	GasLimit   math.HexOrDecimal64
    96  	GasUsed    math.HexOrDecimal64
    97  	Number     math.HexOrDecimal64
    98  	Difficulty *math.HexOrDecimal256
    99  	Alloc      map[common.UnprefixedAddress]GenesisAccount
   100  }
   101  
   102  type genesisAccountMarshaling struct {
   103  	Code       hexutil.Bytes
   104  	Balance    *math.HexOrDecimal256
   105  	Nonce      math.HexOrDecimal64
   106  	Storage    map[storageJSON]storageJSON
   107  	PrivateKey hexutil.Bytes
   108  }
   109  
   110  // storageJSON represents a 256 bit byte array, but allows less than 256 bits when
   111  // unmarshaling from hex.
   112  type storageJSON common.Hash
   113  
   114  func (h *storageJSON) UnmarshalText(text []byte) error {
   115  	text = bytes.TrimPrefix(text, []byte("0x"))
   116  	if len(text) > 64 {
   117  		return fmt.Errorf("too many hex characters in storage key/value %q", text)
   118  	}
   119  	offset := len(h) - len(text)/2 // pad on the left
   120  	if _, err := hex.Decode(h[offset:], text); err != nil {
   121  		fmt.Println(err)
   122  		return fmt.Errorf("invalid hex storage key/value %q", text)
   123  	}
   124  	return nil
   125  }
   126  
   127  func (h storageJSON) MarshalText() ([]byte, error) {
   128  	return hexutil.Bytes(h[:]).MarshalText()
   129  }
   130  
   131  // GenesisMismatchError is raised when trying to overwrite an existing
   132  // genesis block with an incompatible one.
   133  type GenesisMismatchError struct {
   134  	Stored, New common.Hash
   135  }
   136  
   137  func (e *GenesisMismatchError) Error() string {
   138  	return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8])
   139  }
   140  
   141  // SetupGenesisBlock writes or updates the genesis block in db.
   142  // The block that will be used is:
   143  //
   144  //                          genesis == nil       genesis != nil
   145  //                       +------------------------------------------
   146  //     db has no genesis |  main-net default  |  genesis
   147  //     db has genesis    |  from DB           |  genesis (if compatible)
   148  //
   149  // The stored chain configuration will be updated if it is compatible (i.e. does not
   150  // specify a fork block below the local head block). In case of a conflict, the
   151  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   152  //
   153  // The returned chain configuration is never nil.
   154  
   155  func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
   156  	if genesis != nil && genesis.Config == nil {
   157  		return params.AllProtocolChanges, common.Hash{}, errGenesisNoConfig
   158  	}
   159  
   160  	// Just commit the new block if there is no stored genesis block.
   161  	stored := GetCanonicalHash(db, 0)
   162  	if (stored == common.Hash{}) {
   163  		if genesis == nil {
   164  			log.Info("Writing default main-net genesis block")
   165  			genesis = DefaultGenesisBlock()
   166  		} else if genesis.Config.ChainId.Cmp(big.NewInt(3)) == 0 {
   167  			log.Info("Writing default  test net genesis block")
   168  			genesis = DefaultTestnetGenesisBlock()
   169  		} else {
   170  			log.Info("Writing custom genesis block")
   171  		}
   172  		block, err := genesis.Commit(db)
   173  		return genesis.Config, block.Hash(), err
   174  	}
   175  
   176  	// Check whether the genesis block is already written.
   177  	if genesis != nil {
   178  		block, _ := genesis.ToBlock()
   179  		hash := block.Hash()
   180  		if hash != stored {
   181  			return genesis.Config, block.Hash(), &GenesisMismatchError{stored, hash}
   182  		}
   183  	}
   184  
   185  	// Get the existing chain configuration.
   186  	newcfg := genesis.configOrDefault(stored)
   187  	storedcfg, err := GetChainConfig(db, stored)
   188  	if err != nil {
   189  		if err == ErrChainConfigNotFound {
   190  			// This case happens if a genesis write was interrupted.
   191  			log.Warn("Found genesis block without chain config")
   192  			err = WriteChainConfig(db, stored, newcfg)
   193  		}
   194  		return newcfg, stored, err
   195  	}
   196  	// Special case: don't change the existing config of a non-mainnet chain if no new
   197  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   198  	// if we just continued here.
   199  	if genesis == nil && stored != params.MainnetGenesisHash {
   200  		return storedcfg, stored, nil
   201  	}
   202  
   203  	// Check config compatibility and write the config. Compatibility errors
   204  	// are returned to the caller unless we're already at block zero.
   205  	height := GetBlockNumber(db, GetHeadHeaderHash(db))
   206  	if height == missingNumber {
   207  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   208  	}
   209  	compatErr := storedcfg.CheckCompatible(newcfg, height)
   210  	if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
   211  		return newcfg, stored, compatErr
   212  	}
   213  	return newcfg, stored, WriteChainConfig(db, stored, newcfg)
   214  }
   215  
   216  func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
   217  	switch {
   218  	case g != nil:
   219  		return g.Config
   220  	case ghash == params.MainnetGenesisHash:
   221  		return params.WanchainChainConfig
   222  	case ghash == params.TestnetGenesisHash:
   223  		return params.TestnetChainConfig
   224  	case ghash == params.InternalGenesisHash:
   225  		return params.TestnetChainConfig
   226  
   227  	case ghash == params.PlutoGenesisHash:
   228  		return params.PlutoChainConfig
   229  	default:
   230  		return params.AllProtocolChanges
   231  	}
   232  }
   233  
   234  // ToBlock creates the block and state of a genesis specification.
   235  func (g *Genesis) ToBlock() (*types.Block, *state.StateDB) {
   236  	db, _ := ethdb.NewMemDatabase()
   237  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
   238  	for addr, account := range g.Alloc {
   239  		statedb.AddBalance(addr, account.Balance)
   240  		statedb.SetCode(addr, account.Code)
   241  		statedb.SetNonce(addr, account.Nonce)
   242  		for key, value := range account.Storage {
   243  			statedb.SetState(addr, key, value)
   244  		}
   245  	}
   246  	root := statedb.IntermediateRoot(false)
   247  	head := &types.Header{
   248  		Number:     new(big.Int).SetUint64(g.Number),
   249  		Nonce:      types.EncodeNonce(g.Nonce),
   250  		Time:       new(big.Int).SetUint64(g.Timestamp),
   251  		ParentHash: g.ParentHash,
   252  		Extra:      g.ExtraData,
   253  		GasLimit:   new(big.Int).SetUint64(g.GasLimit),
   254  		GasUsed:    new(big.Int).SetUint64(g.GasUsed),
   255  		Difficulty: g.Difficulty,
   256  		MixDigest:  g.Mixhash,
   257  		Coinbase:   g.Coinbase,
   258  		Root:       root,
   259  	}
   260  	if g.GasLimit == 0 {
   261  		head.GasLimit = params.GenesisGasLimit
   262  	}
   263  	if g.Difficulty == nil {
   264  		head.Difficulty = params.GenesisDifficulty
   265  	}
   266  	return types.NewBlock(head, nil, nil, nil), statedb
   267  }
   268  
   269  // Commit writes the block and state of a genesis specification to the database.
   270  // The block is committed as the canonical head block.
   271  func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
   272  	block, statedb := g.ToBlock()
   273  	if block.Number().Sign() != 0 {
   274  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   275  	}
   276  	if _, err := statedb.CommitTo(db, false); err != nil {
   277  		return nil, fmt.Errorf("cannot write state: %v", err)
   278  	}
   279  	if err := WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty); err != nil {
   280  		return nil, err
   281  	}
   282  	if err := WriteBlock(db, block); err != nil {
   283  		return nil, err
   284  	}
   285  	if err := WriteBlockReceipts(db, block.Hash(), block.NumberU64(), nil); err != nil {
   286  		return nil, err
   287  	}
   288  	if err := WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
   289  		return nil, err
   290  	}
   291  	if err := WriteHeadBlockHash(db, block.Hash()); err != nil {
   292  		return nil, err
   293  	}
   294  	if err := WriteHeadHeaderHash(db, block.Hash()); err != nil {
   295  		return nil, err
   296  	}
   297  	config := g.Config
   298  	if config == nil {
   299  		config = params.AllProtocolChanges
   300  	}
   301  	return block, WriteChainConfig(db, block.Hash(), config)
   302  }
   303  
   304  // MustCommit writes the genesis block and state to db, panicking on error.
   305  // The block is committed as the canonical head block.
   306  func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
   307  	block, err := g.Commit(db)
   308  	if err != nil {
   309  		panic(err)
   310  	}
   311  	return block
   312  }
   313  
   314  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   315  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
   316  	g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}}
   317  	return g.MustCommit(db)
   318  }
   319  
   320  // DefaultPPOWTestingGenesisBlock returns the Wanchain ppow testing genesis block
   321  func DefaultPPOWTestingGenesisBlock() *Genesis {
   322  
   323  	key, _ := crypto.HexToECDSA("f1572f76b75b40a7da72d6f2ee7fda3d1189c2d28f0a2f096347055abe344d7f")
   324  	coinbase := crypto.PubkeyToAddress(key.PublicKey)
   325  	return &Genesis{
   326  		Coinbase:   coinbase,
   327  		Config:     params.TestChainConfig,
   328  		Nonce:      66,
   329  		ExtraData:  hexutil.MustDecode("0xf9b32578b4420a36f132db32b56f3831a7cc1804810524175efa012446103d1a04c9f4263a962accdb05642eabc8347ec78e21bdf0d906ba579d423ab5eb9bf02a924367ed9d4f86dfcb1c572cd9a4f80036805b6846f26ac35f2a7d7eda4a2a58f08e8ef073d4e52c506f3f288faa9db1c1e5ae0f1e70f8c38eb01bce9bcb61327532dc5a540da4cf484ae57e98bc5a465c1d2afa6b9376709a525981f53d493a46ef1eb55428b3b88a222d80d23531054ef51dbd100cf8286136659a7d63a38a154e28dbf3e0fd"),
   330  		GasLimit:   0x47b760,
   331  		Difficulty: big.NewInt(1),
   332  		Alloc:      jsonPrealloc(wanchainPPOWTestAllocJson),
   333  	}
   334  }
   335  
   336  // DefaultGenesisBlock returns the Ethereum main net genesis block.
   337  func DefaultGenesisBlock() *Genesis {
   338  	return &Genesis{
   339  		Config:     params.WanchainChainConfig,
   340  		Nonce:      98,
   341  		ExtraData:  hexutil.MustDecode(getMainNetPpwSignStr()),
   342  		GasLimit:   0x2fefd8,
   343  		Difficulty: big.NewInt(1048576),
   344  		//Difficulty: big.NewInt(17179869184),
   345  		Alloc: jsonPrealloc(wanchainAllocJson),
   346  	}
   347  }
   348  
   349  // DefaultTestnetGenesisBlock returns the Ropsten network genesis block.
   350  func DefaultTestnetGenesisBlock() *Genesis {
   351  	return &Genesis{
   352  		Config:     params.TestnetChainConfig,
   353  		Nonce:      28, //same with the version
   354  		ExtraData:  hexutil.MustDecode(getTestNetPpwSignStr()),
   355  		GasLimit:   0x2fefd8,
   356  		Difficulty: big.NewInt(1048576),
   357  		Alloc:      jsonPrealloc(wanchainTestAllocJson),
   358  	}
   359  }
   360  
   361  // DefaultInternalGenesisBlock returns the Rinkeby network genesis block.
   362  func DefaultInternalGenesisBlock() *Genesis {
   363  	return &Genesis{
   364  		Config:     params.InternalChainConfig,
   365  		Nonce:      20,
   366  		ExtraData:  hexutil.MustDecode(getInternalNetPpwSignStr()),
   367  		GasLimit:   0x2fefd8,
   368  		Difficulty: big.NewInt(1),
   369  		Alloc:      jsonPrealloc(wanchainTestAllocJson),
   370  	}
   371  }
   372  
   373  // DefaultPlutoGenesisBlock returns the Pluto network genesis block.
   374  
   375  func DefaultPlutoGenesisBlock() *Genesis {
   376  	return &Genesis{
   377  		Config:     params.PlutoChainConfig,
   378  		Timestamp:  0x59f83144,
   379  		ExtraData:  hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000e8ffc3d0c02c0bfc39b139fa49e2c5475f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   380  		GasLimit:   0x47b760,
   381  		Difficulty: big.NewInt(1),
   382  		Alloc:      jsonPrealloc(PlutoAllocJson),
   383  	}
   384  }
   385  
   386  // DevGenesisBlock returns the 'geth --dev' genesis block.
   387  func DevGenesisBlock() *Genesis {
   388  	return &Genesis{
   389  		Config:     params.AllProtocolChanges,
   390  		Nonce:      42,
   391  		ExtraData:  hexutil.MustDecode("0x9da26fc2e1d6ad9fdd46138906b0104ae68a65d8"),
   392  		GasLimit:   4712388,
   393  		Difficulty: big.NewInt(1),
   394  		Alloc:      jsonPrealloc(wanchainPPOWDevAllocJson),
   395  	}
   396  }
   397  
   398  func decodePrealloc(data string) GenesisAlloc {
   399  	var p []struct{ Addr, Balance *big.Int }
   400  	if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
   401  		panic(err)
   402  	}
   403  	ga := make(GenesisAlloc, len(p))
   404  	for _, account := range p {
   405  		ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
   406  	}
   407  	return ga
   408  }
   409  
   410  func jsonPrealloc(data string) GenesisAlloc {
   411  	var ga GenesisAlloc
   412  	if err := json.Unmarshal([]byte(data), &ga); err != nil {
   413  		panic(err)
   414  	}
   415  	return ga
   416  }