github.com/edxfund/validator@v1.8.16-0.20181020093046-c1def72855da/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/EDXFund/Validator/common"
    29  	"github.com/EDXFund/Validator/common/hexutil"
    30  	"github.com/EDXFund/Validator/common/math"
    31  	"github.com/EDXFund/Validator/core/rawdb"
    32  	"github.com/EDXFund/Validator/core/state"
    33  	"github.com/EDXFund/Validator/core/types"
    34  	"github.com/EDXFund/Validator/ethdb"
    35  	"github.com/EDXFund/Validator/log"
    36  	"github.com/EDXFund/Validator/params"
    37  	"github.com/EDXFund/Validator/rlp"
    38  )
    39  
    40  //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
    41  //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go
    42  
    43  var errGenesisNoConfig = errors.New("genesis has no chain configuration")
    44  
    45  // Genesis specifies the header fields, state of a genesis block. It also defines hard
    46  // fork switch-over blocks through the chain configuration.
    47  type Genesis struct {
    48  	Config     *params.ChainConfig `json:"config"`
    49  	Nonce      uint64              `json:"nonce"`
    50  	Timestamp  uint64              `json:"timestamp"`
    51  	ExtraData  []byte              `json:"extraData"`
    52  	GasLimit   uint64              `json:"gasLimit"   gencodec:"required"`
    53  	Difficulty *big.Int            `json:"difficulty" gencodec:"required"`
    54  	Mixhash    common.Hash         `json:"mixHash"`
    55  	Coinbase   common.Address      `json:"coinbase"`
    56  	Alloc      GenesisAlloc        `json:"alloc"      gencodec:"required"`
    57  
    58  	// These fields are used for consensus tests. Please don't use them
    59  	// in actual genesis blocks.
    60  	Number     uint64      `json:"number"`
    61  	GasUsed    uint64      `json:"gasUsed"`
    62  	ParentHash common.Hash `json:"parentHash"`
    63  }
    64  
    65  // GenesisAlloc specifies the initial state that is part of the genesis block.
    66  type GenesisAlloc map[common.Address]GenesisAccount
    67  
    68  func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
    69  	m := make(map[common.UnprefixedAddress]GenesisAccount)
    70  	if err := json.Unmarshal(data, &m); err != nil {
    71  		return err
    72  	}
    73  	*ga = make(GenesisAlloc)
    74  	for addr, a := range m {
    75  		(*ga)[common.Address(addr)] = a
    76  	}
    77  	return nil
    78  }
    79  
    80  // GenesisAccount is an account in the state of the genesis block.
    81  type GenesisAccount struct {
    82  	Code       []byte                      `json:"code,omitempty"`
    83  	Storage    map[common.Hash]common.Hash `json:"storage,omitempty"`
    84  	Balance    *big.Int                    `json:"balance" gencodec:"required"`
    85  	Nonce      uint64                      `json:"nonce,omitempty"`
    86  	PrivateKey []byte                      `json:"secretKey,omitempty"` // for tests
    87  }
    88  
    89  // field type overrides for gencodec
    90  type genesisSpecMarshaling struct {
    91  	Nonce      math.HexOrDecimal64
    92  	Timestamp  math.HexOrDecimal64
    93  	ExtraData  hexutil.Bytes
    94  	GasLimit   math.HexOrDecimal64
    95  	GasUsed    math.HexOrDecimal64
    96  	Number     math.HexOrDecimal64
    97  	Difficulty *math.HexOrDecimal256
    98  	Alloc      map[common.UnprefixedAddress]GenesisAccount
    99  }
   100  
   101  type genesisAccountMarshaling struct {
   102  	Code       hexutil.Bytes
   103  	Balance    *math.HexOrDecimal256
   104  	Nonce      math.HexOrDecimal64
   105  	Storage    map[storageJSON]storageJSON
   106  	PrivateKey hexutil.Bytes
   107  }
   108  
   109  // storageJSON represents a 256 bit byte array, but allows less than 256 bits when
   110  // unmarshaling from hex.
   111  type storageJSON common.Hash
   112  
   113  func (h *storageJSON) UnmarshalText(text []byte) error {
   114  	text = bytes.TrimPrefix(text, []byte("0x"))
   115  	if len(text) > 64 {
   116  		return fmt.Errorf("too many hex characters in storage key/value %q", text)
   117  	}
   118  	offset := len(h) - len(text)/2 // pad on the left
   119  	if _, err := hex.Decode(h[offset:], text); err != nil {
   120  		fmt.Println(err)
   121  		return fmt.Errorf("invalid hex storage key/value %q", text)
   122  	}
   123  	return nil
   124  }
   125  
   126  func (h storageJSON) MarshalText() ([]byte, error) {
   127  	return hexutil.Bytes(h[:]).MarshalText()
   128  }
   129  
   130  // GenesisMismatchError is raised when trying to overwrite an existing
   131  // genesis block with an incompatible one.
   132  type GenesisMismatchError struct {
   133  	Stored, New common.Hash
   134  }
   135  
   136  func (e *GenesisMismatchError) Error() string {
   137  	return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8])
   138  }
   139  
   140  // SetupGenesisBlock writes or updates the genesis block in db.
   141  // The block that will be used is:
   142  //
   143  //                          genesis == nil       genesis != nil
   144  //                       +------------------------------------------
   145  //     db has no genesis |  main-net default  |  genesis
   146  //     db has genesis    |  from DB           |  genesis (if compatible)
   147  //
   148  // The stored chain configuration will be updated if it is compatible (i.e. does not
   149  // specify a fork block below the local head block). In case of a conflict, the
   150  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   151  //
   152  // The returned chain configuration is never nil.
   153  func SetupGenesisBlock(db ethdb.Database, genesis *Genesis, shardId uint16) (*params.ChainConfig, common.Hash, error) {
   154  
   155  	if genesis != nil && genesis.Config == nil {
   156  		return params.AllEthashProtocolChanges, common.Hash{}, errGenesisNoConfig
   157  	}
   158  
   159  	// Just commit the new block if there is no stored genesis block.
   160  	stored := rawdb.ReadCanonicalHash(db, uint16(shardId), 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  		return genesis.Config, block.Hash(), err
   170  	}
   171  
   172  	// Check whether the genesis block is already written.
   173  	if genesis != nil {
   174  		hash := genesis.ToBlock(nil).Hash()
   175  		if hash != stored {
   176  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   177  		}
   178  	}
   179  
   180  	// Get the existing chain configuration.
   181  	newcfg := genesis.configOrDefault(stored)
   182  	storedcfg := rawdb.ReadChainConfig(db, stored)
   183  	if storedcfg == nil {
   184  		log.Warn("Found genesis block without chain config")
   185  		rawdb.WriteChainConfig(db, stored, newcfg)
   186  		return newcfg, stored, nil
   187  	}
   188  	// Special case: don't change the existing config of a non-mainnet chain if no new
   189  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   190  	// if we just continued here.
   191  	if genesis == nil && stored != params.MainnetGenesisHash {
   192  		return storedcfg, stored, nil
   193  	}
   194  
   195  	// Check config compatibility and write the config. Compatibility errors
   196  	// are returned to the caller unless we're already at block zero.
   197  	_, height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db, shardId))
   198  	if height == nil {
   199  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   200  	}
   201  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   202  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   203  		return newcfg, stored, compatErr
   204  	}
   205  	rawdb.WriteChainConfig(db, stored, newcfg)
   206  	return newcfg, stored, nil
   207  }
   208  
   209  func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
   210  	switch {
   211  	case g != nil:
   212  		return g.Config
   213  	case ghash == params.MainnetGenesisHash:
   214  		return params.MainnetChainConfig
   215  	case ghash == params.TestnetGenesisHash:
   216  		return params.TestnetChainConfig
   217  	default:
   218  		return params.AllEthashProtocolChanges
   219  	}
   220  }
   221  
   222  // ToBlock creates the genesis block and writes state of a genesis specification
   223  // to the given database (or discards it if nil).
   224  func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
   225  	if db == nil {
   226  		db = ethdb.NewMemDatabase()
   227  	}
   228  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
   229  	for addr, account := range g.Alloc {
   230  		statedb.AddBalance(addr, account.Balance)
   231  		statedb.SetCode(addr, account.Code)
   232  		statedb.SetNonce(addr, account.Nonce)
   233  		for key, value := range account.Storage {
   234  			statedb.SetState(addr, key, value)
   235  		}
   236  	}
   237  	root := statedb.IntermediateRoot(false)
   238  	head := &types.Header{
   239  		Number:     new(big.Int).SetUint64(g.Number),
   240  		Nonce:      types.EncodeNonce(g.Nonce),
   241  		Time:       new(big.Int).SetUint64(g.Timestamp),
   242  		ParentHash: g.ParentHash,
   243  		Extra:      g.ExtraData,
   244  		GasLimit:   g.GasLimit,
   245  		GasUsed:    g.GasUsed,
   246  		Difficulty: g.Difficulty,
   247  		MixDigest:  g.Mixhash,
   248  		Coinbase:   g.Coinbase,
   249  		Root:       root,
   250  	}
   251  	if g.GasLimit == 0 {
   252  		head.GasLimit = params.GenesisGasLimit
   253  	}
   254  	if g.Difficulty == nil {
   255  		head.Difficulty = params.GenesisDifficulty
   256  	}
   257  	statedb.Commit(false)
   258  	statedb.Database().TrieDB().Commit(root, true)
   259  
   260  	return types.NewBlock(head, nil, nil)
   261  }
   262  
   263  // Commit writes the block and state of a genesis specification to the database.
   264  // The block is committed as the canonical head block.
   265  func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
   266  	block := g.ToBlock(db)
   267  	if block.Number().Sign() != 0 {
   268  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   269  	}
   270  	shardId := block.Header().ShardId
   271  	rawdb.WriteTd(db, block.Hash(), shardId, block.NumberU64(), g.Difficulty)
   272  	rawdb.WriteBlock(db, block)
   273  	rawdb.WriteReceipts(db, block.Hash(), shardId, block.NumberU64(), nil)
   274  	rawdb.WriteCanonicalHash(db, block.Hash(), shardId, block.NumberU64())
   275  	rawdb.WriteHeadBlockHash(db, block.Hash(), shardId)
   276  	rawdb.WriteHeadHeaderHash(db, block.Hash(), shardId)
   277  
   278  	config := g.Config
   279  	if config == nil {
   280  		config = params.AllEthashProtocolChanges
   281  	}
   282  	rawdb.WriteChainConfig(db, block.Hash(), config)
   283  	return block, nil
   284  }
   285  
   286  // MustCommit writes the genesis block and state to db, panicking on error.
   287  // The block is committed as the canonical head block.
   288  func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
   289  	block, err := g.Commit(db)
   290  	if err != nil {
   291  		panic(err)
   292  	}
   293  	return block
   294  }
   295  
   296  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   297  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
   298  	g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}}
   299  	return g.MustCommit(db)
   300  }
   301  
   302  // DefaultGenesisBlock returns the Ethereum main net genesis block.
   303  func DefaultGenesisBlock() *Genesis {
   304  	return &Genesis{
   305  		Config:     params.MainnetChainConfig,
   306  		Nonce:      66,
   307  		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
   308  		GasLimit:   5000,
   309  		Difficulty: big.NewInt(17179869184),
   310  		Alloc:      decodePrealloc(mainnetAllocData),
   311  	}
   312  }
   313  
   314  // DefaultTestnetGenesisBlock returns the Ropsten network genesis block.
   315  func DefaultTestnetGenesisBlock() *Genesis {
   316  	return &Genesis{
   317  		Config:     params.TestnetChainConfig,
   318  		Nonce:      66,
   319  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
   320  		GasLimit:   16777216,
   321  		Difficulty: big.NewInt(1048576),
   322  		Alloc:      decodePrealloc(testnetAllocData),
   323  	}
   324  }
   325  
   326  // DefaultRinkebyGenesisBlock returns the Rinkeby network genesis block.
   327  func DefaultRinkebyGenesisBlock() *Genesis {
   328  	return &Genesis{
   329  		Config:     params.RinkebyChainConfig,
   330  		Timestamp:  1492009146,
   331  		ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   332  		GasLimit:   4700000,
   333  		Difficulty: big.NewInt(1),
   334  		Alloc:      decodePrealloc(rinkebyAllocData),
   335  	}
   336  }
   337  
   338  // DeveloperGenesisBlock returns the 'geth --dev' genesis block. Note, this must
   339  // be seeded with the
   340  func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
   341  	// Override the default period to the user requested one
   342  	config := *params.AllCliqueProtocolChanges
   343  	config.Clique.Period = period
   344  
   345  	// Assemble and return the genesis with the precompiles and faucet pre-funded
   346  	return &Genesis{
   347  		Config:     &config,
   348  		ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...),
   349  		GasLimit:   6283185,
   350  		Difficulty: big.NewInt(1),
   351  		Alloc: map[common.Address]GenesisAccount{
   352  			common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
   353  			common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
   354  			common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
   355  			common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
   356  			common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
   357  			common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
   358  			common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
   359  			common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
   360  			faucet:                           {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
   361  		},
   362  	}
   363  }
   364  
   365  func decodePrealloc(data string) GenesisAlloc {
   366  	var p []struct{ Addr, Balance *big.Int }
   367  	if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
   368  		panic(err)
   369  	}
   370  	ga := make(GenesisAlloc, len(p))
   371  	for _, account := range p {
   372  		ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
   373  	}
   374  	return ga
   375  }