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