github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/core/genesis.go (about)

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