github.com/bcskill/bcschain/v3@v3.4.9-beta2/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  	"math/rand"
    27  	"time"
    28  
    29  	"github.com/bcskill/bcschain/v3/common"
    30  	"github.com/bcskill/bcschain/v3/common/hexutil"
    31  	"github.com/bcskill/bcschain/v3/common/math"
    32  	"github.com/bcskill/bcschain/v3/core/rawdb"
    33  	"github.com/bcskill/bcschain/v3/core/state"
    34  	"github.com/bcskill/bcschain/v3/core/types"
    35  	"github.com/bcskill/bcschain/v3/ethdb"
    36  	"github.com/bcskill/bcschain/v3/log"
    37  	"github.com/bcskill/bcschain/v3/params"
    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  	Signers    []common.Address    `json:"signers"`
    53  	Voters     []common.Address    `json:"voters"`
    54  	Signer     []byte              `json:"signer"`
    55  	GasLimit   uint64              `json:"gasLimit"   gencodec:"required"`
    56  	Difficulty *big.Int            `json:"difficulty" gencodec:"required"`
    57  	Mixhash    common.Hash         `json:"mixHash"`
    58  	Coinbase   common.Address      `json:"coinbase"`
    59  	Alloc      GenesisAlloc        `json:"alloc"      gencodec:"required"`
    60  
    61  	// These fields are used for consensus tests. Please don't use them
    62  	// in actual genesis blocks.
    63  	Number     uint64      `json:"number"`
    64  	GasUsed    uint64      `json:"gasUsed"`
    65  	ParentHash common.Hash `json:"parentHash"`
    66  }
    67  
    68  // GenesisAlloc specifies the initial state that is part of the genesis block.
    69  type GenesisAlloc map[common.Address]GenesisAccount
    70  
    71  func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
    72  	m := make(map[common.UnprefixedAddress]GenesisAccount)
    73  	if err := json.Unmarshal(data, &m); err != nil {
    74  		return err
    75  	}
    76  	*ga = make(GenesisAlloc)
    77  	for addr, a := range m {
    78  		(*ga)[common.Address(addr)] = a
    79  	}
    80  	return nil
    81  }
    82  
    83  func (ga *GenesisAlloc) Total() *big.Int {
    84  	sum := new(big.Int)
    85  	if ga == nil {
    86  		return sum
    87  	}
    88  	for _, st := range *ga {
    89  		sum = sum.Add(sum, st.Balance)
    90  	}
    91  	return sum
    92  }
    93  
    94  // GenesisAccount is an account in the state of the genesis block.
    95  type GenesisAccount struct {
    96  	Code       []byte                      `json:"code,omitempty"`
    97  	Storage    map[common.Hash]common.Hash `json:"storage,omitempty"`
    98  	Balance    *big.Int                    `json:"balance" gencodec:"required"`
    99  	Nonce      uint64                      `json:"nonce,omitempty"`
   100  	PrivateKey []byte                      `json:"secretKey,omitempty"` // for tests
   101  }
   102  
   103  // field type overrides for gencodec
   104  type genesisSpecMarshaling struct {
   105  	Nonce      math.HexOrDecimal64
   106  	Timestamp  math.HexOrDecimal64
   107  	ExtraData  hexutil.Bytes
   108  	Signer     hexutil.Bytes
   109  	GasLimit   math.HexOrDecimal64
   110  	GasUsed    math.HexOrDecimal64
   111  	Number     math.HexOrDecimal64
   112  	Difficulty *math.HexOrDecimal256
   113  	Alloc      map[common.UnprefixedAddress]GenesisAccount
   114  }
   115  
   116  type genesisAccountMarshaling struct {
   117  	Code       hexutil.Bytes
   118  	Balance    *math.HexOrDecimal256
   119  	Nonce      math.HexOrDecimal64
   120  	Storage    map[storageJSON]storageJSON
   121  	PrivateKey hexutil.Bytes
   122  }
   123  
   124  // storageJSON represents a 256 bit byte array, but allows less than 256 bits when
   125  // unmarshaling from hex.
   126  type storageJSON common.Hash
   127  
   128  func (h *storageJSON) UnmarshalText(text []byte) error {
   129  	text = bytes.TrimPrefix(text, []byte("0x"))
   130  	if len(text) > 64 {
   131  		return fmt.Errorf("too many hex characters in storage key/value %q", text)
   132  	}
   133  	offset := len(h) - len(text)/2 // pad on the left
   134  	if _, err := hex.Decode(h[offset:], text); err != nil {
   135  		fmt.Println(err)
   136  		return fmt.Errorf("invalid hex storage key/value %q", text)
   137  	}
   138  	return nil
   139  }
   140  
   141  func (h storageJSON) MarshalText() ([]byte, error) {
   142  	return hexutil.Bytes(h[:]).MarshalText()
   143  }
   144  
   145  // GenesisMismatchError is raised when trying to overwrite an existing
   146  // genesis block with an incompatible one.
   147  type GenesisMismatchError struct {
   148  	Stored, New common.Hash
   149  }
   150  
   151  func (e *GenesisMismatchError) Error() string {
   152  	return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8])
   153  }
   154  
   155  // SetupGenesisBlock writes or updates the genesis block in db.
   156  // The block that will be used is:
   157  //
   158  //                          genesis == nil       genesis != nil
   159  //                       +------------------------------------------
   160  //     db has no genesis |  main-net default  |  genesis
   161  //     db has genesis    |  from DB           |  genesis (if compatible)
   162  //
   163  // The stored chain configuration will be updated if it is compatible (i.e. does not
   164  // specify a fork block below the local head block). In case of a conflict, the
   165  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   166  //
   167  // The returned chain configuration is never nil.
   168  func SetupGenesisBlock(db common.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
   169  	return SetupGenesisBlockWithOverride(db, genesis, nil)
   170  }
   171  func SetupGenesisBlockWithOverride(db common.Database, genesis *Genesis, constantinopleOverride *big.Int) (*params.ChainConfig, common.Hash, error) {
   172  	if genesis != nil && genesis.Config == nil {
   173  		return params.AllCliqueProtocolChanges, common.Hash{}, errGenesisNoConfig
   174  	}
   175  
   176  	// Just commit the new block if there is no stored genesis block.
   177  	stored := rawdb.ReadCanonicalHash(db, 0)
   178  	if (stored == common.Hash{}) {
   179  		if genesis == nil {
   180  			log.Info("Writing default main-net genesis block")
   181  			genesis = DefaultGenesisBlock()
   182  		} else {
   183  			log.Info("Writing custom genesis block")
   184  		}
   185  		block, err := genesis.Commit(db)
   186  		return genesis.Config, block.Hash(), err
   187  	}
   188  
   189  	// Check whether the genesis block is already written.
   190  	if genesis != nil {
   191  		hash := genesis.ToBlock(nil).Hash()
   192  		if hash != stored {
   193  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   194  		}
   195  	}
   196  
   197  	// Get the existing chain configuration.
   198  	newcfg := genesis.configOrDefault(stored)
   199  	if constantinopleOverride != nil {
   200  		newcfg.ConstantinopleBlock = constantinopleOverride
   201  		newcfg.PetersburgBlock = constantinopleOverride
   202  	}
   203  	storedcfg := rawdb.ReadChainConfig(db.GlobalTable(), stored)
   204  	if storedcfg == nil {
   205  		// This case happens if a genesis write was interrupted.
   206  		log.Warn("Found genesis block without chain config")
   207  		rawdb.WriteChainConfig(db.GlobalTable(), stored, newcfg)
   208  		return newcfg, stored, nil
   209  	}
   210  	// Special case: don't change the existing config of a non-mainnet chain if no new
   211  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   212  	// if we just continued here.
   213  	if genesis == nil && stored != params.MainnetGenesisHash {
   214  		return storedcfg, stored, nil
   215  	}
   216  
   217  	// Check config compatibility and write the config. Compatibility errors
   218  	// are returned to the caller unless we're already at block zero.
   219  	height := rawdb.ReadHeaderNumber(db.GlobalTable(), rawdb.ReadHeadHeaderHash(db.GlobalTable()))
   220  	if height == nil {
   221  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   222  	}
   223  	compatErr := storedcfg.CheckCompatible(newcfg, *height)
   224  	if compatErr != nil && *height != 0 && compatErr.RewindTo != 0 {
   225  		return newcfg, stored, compatErr
   226  	}
   227  	rawdb.WriteChainConfig(db.GlobalTable(), stored, newcfg)
   228  	return newcfg, stored, nil
   229  }
   230  
   231  func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
   232  	switch {
   233  	case g != nil:
   234  		return g.Config
   235  	case ghash == params.MainnetGenesisHash:
   236  		return params.MainnetChainConfig
   237  	case ghash == params.TestnetGenesisHash:
   238  		return params.TestnetChainConfig
   239  	default:
   240  		return params.AllCliqueProtocolChanges
   241  	}
   242  }
   243  
   244  // ToBlock creates the genesis block and writes state of a genesis specification
   245  // to the given database (or discards it if nil).
   246  func (g *Genesis) ToBlock(db common.Database) *types.Block {
   247  	if db == nil {
   248  		db = ethdb.NewMemDatabase()
   249  	}
   250  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
   251  	for addr, account := range g.Alloc {
   252  		statedb.AddBalance(addr, account.Balance)
   253  		statedb.SetCode(addr, account.Code)
   254  		statedb.SetNonce(addr, account.Nonce)
   255  		for key, value := range account.Storage {
   256  			statedb.SetState(addr, key, value)
   257  		}
   258  	}
   259  	root := statedb.IntermediateRoot(false)
   260  	head := &types.Header{
   261  		Number:     new(big.Int).SetUint64(g.Number),
   262  		Nonce:      types.EncodeNonce(g.Nonce),
   263  		Time:       new(big.Int).SetUint64(g.Timestamp),
   264  		ParentHash: g.ParentHash,
   265  		Extra:      g.ExtraData,
   266  		Signers:    g.Signers,
   267  		Voters:     g.Voters,
   268  		Signer:     g.Signer,
   269  		GasLimit:   g.GasLimit,
   270  		GasUsed:    g.GasUsed,
   271  		Difficulty: g.Difficulty,
   272  		MixDigest:  g.Mixhash,
   273  		Coinbase:   g.Coinbase,
   274  		Root:       root,
   275  	}
   276  	if g.GasLimit == 0 {
   277  		head.GasLimit = params.GenesisGasLimit
   278  	}
   279  	if g.Difficulty == nil {
   280  		head.Difficulty = big.NewInt(1)
   281  	}
   282  	if _, err := statedb.Commit(false); err != nil {
   283  		log.Error("Cannot commit genesis to state db", "err", err)
   284  	}
   285  	if err := statedb.Database().TrieDB().Commit(root, true); err != nil {
   286  		log.Error("Cannot commit genesis to trie db", "err", err)
   287  	}
   288  
   289  	return types.NewBlock(head, nil, nil, nil)
   290  }
   291  
   292  // Commit writes the block and state of a genesis specification to the database.
   293  // The block is committed as the canonical head block.
   294  func (g *Genesis) Commit(db common.Database) (*types.Block, error) {
   295  	block := g.ToBlock(db)
   296  	if block.Number().Sign() != 0 {
   297  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   298  	}
   299  	rawdb.WriteTd(db.GlobalTable(), block.Hash(), block.NumberU64(), g.Difficulty)
   300  	rawdb.WriteBlock(db, block)
   301  	rawdb.WriteReceipts(db.ReceiptTable(), block.Hash(), block.NumberU64(), nil)
   302  	rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
   303  	rawdb.WriteHeadBlockHash(db.GlobalTable(), block.Hash())
   304  	rawdb.WriteHeadHeaderHash(db.GlobalTable(), block.Hash())
   305  	config := g.Config
   306  	if config == nil {
   307  		config = params.AllCliqueProtocolChanges
   308  	}
   309  	rawdb.WriteChainConfig(db.GlobalTable(), block.Hash(), config)
   310  	return block, nil
   311  }
   312  
   313  // MustCommit writes the genesis block and state to db, panicking on error.
   314  // The block is committed as the canonical head block.
   315  func (g *Genesis) MustCommit(db common.Database) *types.Block {
   316  	block, err := g.Commit(db)
   317  	if err != nil {
   318  		panic(err)
   319  	}
   320  	return block
   321  }
   322  
   323  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   324  func GenesisBlockForTesting(db common.Database, addr common.Address, balance *big.Int) *types.Block {
   325  	g := Genesis{
   326  		Config: params.AllCliqueProtocolChanges,
   327  		Alloc:  GenesisAlloc{addr: {Balance: balance}},
   328  		Signer: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   329  	}
   330  	return g.MustCommit(db)
   331  }
   332  
   333  // DefaultGenesisBlock returns the GoChain main net genesis block.
   334  func DefaultGenesisBlock() *Genesis {
   335  	allocAddr := common.HexToAddress("0xF75B6E2D2d69Da07f2940e239E25229350f8103f")
   336  	alloc, ok := new(big.Int).SetString("1000000000000000000000000000", 10)
   337  	if !ok {
   338  		panic("failed to parse big.Int string")
   339  	}
   340  	var extra = []byte("GoChain")
   341  	return &Genesis{
   342  		Config:     params.MainnetChainConfig,
   343  		Timestamp:  1526400000,
   344  		ExtraData:  append(extra, make([]byte, 32-len(extra))...),
   345  		GasLimit:   params.GenesisGasLimit,
   346  		Difficulty: big.NewInt(1),
   347  		Signers: []common.Address{
   348  			common.HexToAddress("0xed7f2e81b0264177e0df8f275f97fd74fa51a896"),
   349  			common.HexToAddress("0x3ad14430951aba12068a8167cebe3ddd57614432"),
   350  			common.HexToAddress("0x3729d2e93e8037f87a2c9afe34cb84b7069e4dea"),
   351  			common.HexToAddress("0xf6290b7f9f871d21317acc259f2ae23c0aa69c73"),
   352  			common.HexToAddress("0xf7678aa7f42bc017f3d6011ca27aed400647960d"),
   353  		},
   354  		Voters: []common.Address{
   355  			common.HexToAddress("0xed7f2e81b0264177e0df8f275f97fd74fa51a896"),
   356  		},
   357  		Signer: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   358  		Alloc:  GenesisAlloc{allocAddr: {Balance: alloc}},
   359  	}
   360  }
   361  
   362  // DefaultTestnetGenesisBlock returns the GoChain Testnet network genesis block.
   363  func DefaultTestnetGenesisBlock() *Genesis {
   364  	alloc, ok := new(big.Int).SetString("1000000000000000000000000000", 10)
   365  	if !ok {
   366  		panic("failed to parse big.Int string")
   367  	}
   368  	return &Genesis{
   369  		Config:     params.TestnetChainConfig,
   370  		Timestamp:  1526048200,
   371  		ExtraData:  hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000"),
   372  		GasLimit:   params.GenesisGasLimit,
   373  		Difficulty: big.NewInt(1),
   374  		Signers: []common.Address{
   375  			common.HexToAddress("0x7aeceb5d345a01f8014a4320ab1f3d467c0c086a"),
   376  			common.HexToAddress("0xdd7e460302a911f9162a208370cdcdc37b892453"),
   377  			common.HexToAddress("0x10a8a552c8a8945f32f6fded5e44d9101b3491d8"),
   378  		},
   379  		Voters: []common.Address{
   380  			common.HexToAddress("0x7aeceb5d345a01f8014a4320ab1f3d467c0c086a"),
   381  		},
   382  		Signer: hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   383  		Alloc: GenesisAlloc{
   384  			common.HexToAddress("0x2Fe70F1Df222C85ad6Dd24a3376Eb5ac32136978"): {
   385  				Balance: alloc,
   386  			},
   387  		},
   388  	}
   389  }
   390  
   391  // DeveloperGenesisBlock returns the 'gochain --dev' genesis block. Note, this must
   392  // be seeded with the faucet address.
   393  func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
   394  	// Override the default period to the user requested one
   395  	config := *params.AllCliqueProtocolChanges
   396  	config.ChainId = big.NewInt(int64(rand.Int31()) + 1000)
   397  	config.Clique.Period = period
   398  
   399  	alloc, ok := new(big.Int).SetString("1000000000000000000000000000", 10)
   400  	if !ok {
   401  		panic("failed to parse big.Int string")
   402  	}
   403  	var extra = []byte(faucet.Hex())[:32]
   404  	// Assemble and return the genesis with the precompiles and faucet pre-funded
   405  	return &Genesis{
   406  		Config:     &config,
   407  		Timestamp:  uint64(time.Now().Unix()),
   408  		ExtraData:  append(extra, make([]byte, 32-len(extra))...),
   409  		GasLimit:   params.GenesisGasLimit,
   410  		Difficulty: big.NewInt(1),
   411  		Signers:    []common.Address{faucet},
   412  		Voters:     []common.Address{faucet},
   413  		Signer:     hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   414  		Alloc:      GenesisAlloc{faucet: {Balance: alloc}},
   415  	}
   416  }
   417  
   418  // LocalGenesisBlock returns the 'gochain --local' genesis block.
   419  func LocalGenesisBlock(period uint64, signer common.Address, alloc GenesisAlloc) *Genesis {
   420  	// Override the default period to the user requested one
   421  	config := *params.AllCliqueProtocolChanges
   422  	config.ChainId = big.NewInt(int64(rand.Int31()) + 1000)
   423  	config.Clique.Period = period
   424  
   425  	var extra = []byte(signer.Hex())[:32]
   426  	// Assemble and return the genesis with the precompiles and seeds pre-funded
   427  	return &Genesis{
   428  		Config:     &config,
   429  		Timestamp:  uint64(time.Now().Unix()),
   430  		ExtraData:  append(extra, make([]byte, 32-len(extra))...),
   431  		GasLimit:   params.GenesisGasLimit,
   432  		Difficulty: big.NewInt(1),
   433  		Signers:    []common.Address{signer},
   434  		Voters:     []common.Address{signer},
   435  		Signer:     hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   436  		Alloc:      alloc,
   437  	}
   438  }