github.com/arieschain/arieschain@v0.0.0-20191023063405-37c074544356/core/genesis.go (about)

     1  package core
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/hex"
     6  	"encoding/json"
     7  	"errors"
     8  	"fmt"
     9  	"math/big"
    10  	"strings"
    11  
    12  	"github.com/quickchainproject/quickchain/common"
    13  	"github.com/quickchainproject/quickchain/common/hexutil"
    14  	"github.com/quickchainproject/quickchain/common/math"
    15  	"github.com/quickchainproject/quickchain/core/state"
    16  	"github.com/quickchainproject/quickchain/core/types"
    17  	"github.com/quickchainproject/quickchain/qctdb"
    18  	"github.com/quickchainproject/quickchain/log"
    19  	"github.com/quickchainproject/quickchain/params"
    20  	"github.com/quickchainproject/quickchain/rlp"
    21  )
    22  
    23  //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
    24  //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go
    25  
    26  var errGenesisNoConfig = errors.New("genesis has no chain configuration")
    27  
    28  // Genesis specifies the header fields, state of a genesis block. It also defines hard
    29  // fork switch-over blocks through the chain configuration.
    30  type Genesis struct {
    31  	Config     *params.ChainConfig `json:"config"`
    32  	Nonce      uint64              `json:"nonce"`
    33  	Timestamp  uint64              `json:"timestamp"`
    34  	ExtraData  []byte              `json:"extraData"`
    35  	GasLimit   uint64              `json:"gasLimit"   gencodec:"required"`
    36  	Difficulty *big.Int            `json:"difficulty" gencodec:"required"`
    37  	Mixhash    common.Hash         `json:"mixHash"`
    38  	Coinbase   common.Address      `json:"coinbase"`
    39  	Alloc      GenesisAlloc        `json:"alloc"      gencodec:"required"`
    40  
    41  	// These fields are used for consensus tests. Please don't use them
    42  	// in actual genesis blocks.
    43  	Number     uint64      `json:"number"`
    44  	GasUsed    uint64      `json:"gasUsed"`
    45  	ParentHash common.Hash `json:"parentHash"`
    46  }
    47  
    48  // GenesisAlloc specifies the initial state that is part of the genesis block.
    49  type GenesisAlloc map[common.Address]GenesisAccount
    50  
    51  func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
    52  	m := make(map[common.UnprefixedAddress]GenesisAccount)
    53  	if err := json.Unmarshal(data, &m); err != nil {
    54  		return err
    55  	}
    56  	*ga = make(GenesisAlloc)
    57  	for addr, a := range m {
    58  		(*ga)[common.Address(addr)] = a
    59  	}
    60  	return nil
    61  }
    62  
    63  // GenesisAccount is an account in the state of the genesis block.
    64  type GenesisAccount struct {
    65  	Code       []byte                      `json:"code,omitempty"`
    66  	Storage    map[common.Hash]common.Hash `json:"storage,omitempty"`
    67  	Balance    *big.Int                    `json:"balance" gencodec:"required"`
    68  	Nonce      uint64                      `json:"nonce,omitempty"`
    69  	PrivateKey []byte                      `json:"secretKey,omitempty"` // for tests
    70  }
    71  
    72  // field type overrides for gencodec
    73  type genesisSpecMarshaling struct {
    74  	Nonce      math.HexOrDecimal64
    75  	Timestamp  math.HexOrDecimal64
    76  	ExtraData  hexutil.Bytes
    77  	GasLimit   math.HexOrDecimal64
    78  	GasUsed    math.HexOrDecimal64
    79  	Number     math.HexOrDecimal64
    80  	Difficulty *math.HexOrDecimal256
    81  	Alloc      map[common.UnprefixedAddress]GenesisAccount
    82  }
    83  
    84  type genesisAccountMarshaling struct {
    85  	Code       hexutil.Bytes
    86  	Balance    *math.HexOrDecimal256
    87  	Nonce      math.HexOrDecimal64
    88  	Storage    map[storageJSON]storageJSON
    89  	PrivateKey hexutil.Bytes
    90  }
    91  
    92  // storageJSON represents a 256 bit byte array, but allows less than 256 bits when
    93  // unmarshaling from hex.
    94  type storageJSON common.Hash
    95  
    96  func (h *storageJSON) UnmarshalText(text []byte) error {
    97  	text = bytes.TrimPrefix(text, []byte("0x"))
    98  	if len(text) > 64 {
    99  		return fmt.Errorf("too many hex characters in storage key/value %q", text)
   100  	}
   101  	offset := len(h) - len(text)/2 // pad on the left
   102  	if _, err := hex.Decode(h[offset:], text); err != nil {
   103  		fmt.Println(err)
   104  		return fmt.Errorf("invalid hex storage key/value %q", text)
   105  	}
   106  	return nil
   107  }
   108  
   109  func (h storageJSON) MarshalText() ([]byte, error) {
   110  	return hexutil.Bytes(h[:]).MarshalText()
   111  }
   112  
   113  // GenesisMismatchError is raised when trying to overwrite an existing
   114  // genesis block with an incompatible one.
   115  type GenesisMismatchError struct {
   116  	Stored, New common.Hash
   117  }
   118  
   119  func (e *GenesisMismatchError) Error() string {
   120  	return fmt.Sprintf("database already contains an incompatible genesis block (have %x, new %x)", e.Stored[:8], e.New[:8])
   121  }
   122  
   123  // SetupGenesisBlock writes or updates the genesis block in db.
   124  // The block that will be used is:
   125  //
   126  //                          genesis == nil       genesis != nil
   127  //                       +------------------------------------------
   128  //     db has no genesis |  main-net default  |  genesis
   129  //     db has genesis    |  from DB           |  genesis (if compatible)
   130  //
   131  // The stored chain configuration will be updated if it is compatible (i.e. does not
   132  // specify a fork block below the local head block). In case of a conflict, the
   133  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   134  //
   135  // The returned chain configuration is never nil.
   136  func SetupGenesisBlock(db qctdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
   137  	if genesis != nil && genesis.Config == nil {
   138  		return params.AllDPOSProtocolChanges, common.Hash{}, errGenesisNoConfig
   139  	}
   140  
   141  	// Just commit the new block if there is no stored genesis block.
   142  	stored := GetCanonicalHash(db, 0)
   143  	if (stored == common.Hash{}) {
   144  		if genesis == nil {
   145  			log.Info("Writing default main-net genesis block")
   146  			genesis = DefaultGenesisBlock()
   147  		} else {
   148  			log.Info("Writing custom genesis block")
   149  		}
   150  		block, err := genesis.Commit(db)
   151  		return genesis.Config, block.Hash(), err
   152  	}
   153  
   154  	// Check whether the genesis block is already written.
   155  	if genesis != nil {
   156  		hash := genesis.ToBlock(nil).Hash()
   157  		if hash != stored {
   158  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   159  		}
   160  	}
   161  
   162  	// Get the existing chain configuration.
   163  	newcfg := genesis.configOrDefault(stored)
   164  	storedcfg, err := GetChainConfig(db, stored)
   165  	if err != nil {
   166  		if err == ErrChainConfigNotFound {
   167  			// This case happens if a genesis write was interrupted.
   168  			log.Warn("Found genesis block without chain config")
   169  			err = WriteChainConfig(db, stored, newcfg)
   170  		}
   171  		return newcfg, stored, err
   172  	}
   173  	// Special case: don't change the existing config of a non-mainnet chain if no new
   174  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   175  	// if we just continued here.
   176  	if genesis == nil && stored != params.MainnetGenesisHash {
   177  		return storedcfg, stored, nil
   178  	}
   179  
   180  	// Check config compatibility and write the config. Compatibility errors
   181  	// are returned to the caller unless we're already at block zero.
   182  	height := GetBlockNumber(db, GetHeadHeaderHash(db))
   183  	if height == missingNumber {
   184  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   185  	}
   186  	compatErr := storedcfg.CheckCompatible(newcfg, height)
   187  	if compatErr != nil && height != 0 && compatErr.RewindTo != 0 {
   188  		return newcfg, stored, compatErr
   189  	}
   190  	return newcfg, stored, WriteChainConfig(db, stored, newcfg)
   191  }
   192  
   193  func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
   194  	switch {
   195  	case g != nil:
   196  		return g.Config
   197  	case ghash == params.MainnetGenesisHash:
   198  		return params.MainnetChainConfig
   199  	case ghash == params.TestnetGenesisHash:
   200  		return params.TestnetChainConfig
   201  	default:
   202  		return params.AllDPOSProtocolChanges
   203  	}
   204  }
   205  
   206  // ToBlock creates the genesis block and writes state of a genesis specification
   207  // to the given database (or discards it if nil).
   208  func (g *Genesis) ToBlock(db qctdb.Database) *types.Block {
   209  	if db == nil {
   210  		db, _ = qctdb.NewMemDatabase()
   211  	}
   212  	statedb, _ := state.New(common.Hash{}, state.NewDatabase(db))
   213  	for addr, account := range g.Alloc {
   214  		statedb.AddBalance(addr, account.Balance)
   215  		statedb.SetCode(addr, account.Code)
   216  		statedb.SetNonce(addr, account.Nonce)
   217  		for key, value := range account.Storage {
   218  			statedb.SetState(addr, key, value)
   219  		}
   220  	}
   221  	root := statedb.IntermediateRoot(false)
   222  	// add dposcontext
   223  	dposContext := initGenesisDposContext(g, db)
   224  	dposContextProto := dposContext.ToProto()
   225  	head := &types.Header{
   226  		Number:      new(big.Int).SetUint64(g.Number),
   227  		Nonce:       types.EncodeNonce(g.Nonce),
   228  		Time:        new(big.Int).SetUint64(g.Timestamp),
   229  		ParentHash:  g.ParentHash,
   230  		Extra:       g.ExtraData,
   231  		GasLimit:    g.GasLimit,
   232  		GasUsed:     g.GasUsed,
   233  		Difficulty:  g.Difficulty,
   234  		MixDigest:   g.Mixhash,
   235  		Coinbase:    g.Coinbase,
   236  		Root:        root,
   237  		DposContext: dposContextProto,
   238  	}
   239  	if g.GasLimit == 0 {
   240  		head.GasLimit = params.GenesisGasLimit
   241  	}
   242  	if g.Difficulty == nil {
   243  		head.Difficulty = params.GenesisDifficulty
   244  	}
   245  
   246  	statedb.Commit(false)
   247  	statedb.Database().TrieDB().Commit(root, true)
   248  
   249  	block := types.NewBlock(head, nil, nil, nil)
   250  	block.DposContext = dposContext
   251  
   252  	return block
   253  }
   254  
   255  // Commit writes the block and state of a genesis specification to the database.
   256  // The block is committed as the canonical head block.
   257  func (g *Genesis) Commit(db qctdb.Database) (*types.Block, error) {
   258  	block := g.ToBlock(db)
   259  	// add dposcontext
   260  	if _, err := block.DposContext.Commit(); err != nil {
   261  		return nil, err
   262  	}
   263  	if block.Number().Sign() != 0 {
   264  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   265  	}
   266  	if err := WriteTd(db, block.Hash(), block.NumberU64(), g.Difficulty); err != nil {
   267  		return nil, err
   268  	}
   269  	if err := WriteBlock(db, block); err != nil {
   270  		return nil, err
   271  	}
   272  	if err := WriteBlockReceipts(db, block.Hash(), block.NumberU64(), nil); err != nil {
   273  		return nil, err
   274  	}
   275  	if err := WriteCanonicalHash(db, block.Hash(), block.NumberU64()); err != nil {
   276  		return nil, err
   277  	}
   278  	if err := WriteHeadBlockHash(db, block.Hash()); err != nil {
   279  		return nil, err
   280  	}
   281  	if err := WriteHeadHeaderHash(db, block.Hash()); err != nil {
   282  		return nil, err
   283  	}
   284  	config := g.Config
   285  	if config == nil {
   286  		config = params.AllDPOSProtocolChanges
   287  	}
   288  	return block, WriteChainConfig(db, block.Hash(), config)
   289  }
   290  
   291  // MustCommit writes the genesis block and state to db, panicking on error.
   292  // The block is committed as the canonical head block.
   293  func (g *Genesis) MustCommit(db qctdb.Database) *types.Block {
   294  	block, err := g.Commit(db)
   295  	if err != nil {
   296  		panic(err)
   297  	}
   298  	return block
   299  }
   300  
   301  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   302  func GenesisBlockForTesting(db qctdb.Database, addr common.Address, balance *big.Int) *types.Block {
   303  	g := Genesis{Alloc: GenesisAlloc{addr: {Balance: balance}}}
   304  	return g.MustCommit(db)
   305  }
   306  
   307  // DefaultGenesisBlock returns the Ethereum main net genesis block.
   308  func DefaultGenesisBlock() *Genesis {
   309  	return &Genesis{
   310  		Config:    params.MainnetChainConfig,
   311  		Timestamp: 1492009146,
   312  		//ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   313  		ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e5311494Fd08DAbB2b3De991250ff628260CAd7F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   314  		GasLimit:   500000000,
   315  		Difficulty: big.NewInt(1),
   316  		Alloc:      decodePrealloc(rinkebyAllocData),
   317  	}
   318  }
   319  
   320  // DefaultTestnetGenesisBlock returns the Ropsten network genesis block.
   321  func DefaultTestnetGenesisBlock() *Genesis {
   322  	return &Genesis{
   323  		Config:    params.TestnetChainConfig,
   324  		Timestamp: 1492009146,
   325  		//ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   326  		ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e5311494Fd08DAbB2b3De991250ff628260CAd7F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   327  		GasLimit:   500000000,
   328  		Difficulty: big.NewInt(1),
   329  		Alloc:      decodePrealloc(rinkebyAllocData),
   330  	}
   331  }
   332  
   333  // DefaultPOAGenesisBlock returns the Ropsten network genesis block.
   334  func DefaultPOAGenesisBlock() *Genesis {
   335  	return &Genesis{
   336  		Config:    params.POAChainConfig,
   337  		Timestamp: 1492009146,
   338  		//ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e42eb768f2244c8811c63729a21a3569731535f067ffc57839b00206d1ad20c69a1981b489f772031b279182d99e65703f0076e4812653aab85fca0f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   339  		ExtraData:  hexutil.MustDecode("0x52657370656374206d7920617574686f7269746168207e452e436172746d616e5311494Fd08DAbB2b3De991250ff628260CAd7F70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"),
   340  		GasLimit:   500000000,
   341  		Difficulty: big.NewInt(1),
   342  		Alloc:      decodePrealloc(rinkebyAllocData),
   343  	}
   344  }
   345  
   346  // DefaultBFTGenesisBlock returns the BFT network genesis block.
   347  func DefaultBFTGenesisBlock() *Genesis {
   348  	return &Genesis{
   349  		Config:     params.BFTChainConfig,
   350  		Timestamp:  1496993285,
   351  		//ExtraData:  hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000f85ad5945311494Fd08DAbB2b3De991250ff628260CAd7F7b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"),
   352  		ExtraData:  hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000f85ad5945311494fd08dabb2b3de991250ff628260cad7f7b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"),
   353  		GasLimit:   500000000,
   354  		Difficulty: big.NewInt(1),
   355  		Mixhash:    common.HexToHash("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365"),
   356  		Alloc:      decodePrealloc(bftAllocData),
   357  	}
   358  }
   359  
   360  // DefaultDBFTGenesisBlock returns the DBFT network genesis block.
   361  func DefaultDBFTGenesisBlock() *Genesis {
   362  	return &Genesis{
   363  		Config:     params.DBFTChainConfig,
   364  		Timestamp:  1496993285,
   365  		//ExtraData:  hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000f89af854945311494Fd08DAbB2b3De991250ff628260CAd7F7945311494Fd08DAbB2b3De991250ff628260CAd7F79437089dabe8916b26b3f0f293bfbd314578cf30cf94a487489e4bb7da1a493bfdf43204e051cae4df60b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"),//2vs
   366  		ExtraData:  hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000f85ad5945311494fd08dabb2b3de991250ff628260cad7f7b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"),//1vs
   367  		//ExtraData:  hexutil.MustDecode("0x0000000000000000000000000000000000000000000000000000000000000000f85ad5945311494Fd08DAbB2b3De991250ff628260CAd7F7b8410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0"),//2vs
   368  		GasLimit:   500000000,
   369  		Difficulty: big.NewInt(1),
   370  		Mixhash:    common.HexToHash("0x63746963616c2062797a616e74696e65206661756c7420746f6c6572616e6365"),
   371  		Alloc:      decodePrealloc(dbftAllocData),
   372  	}
   373  }
   374  
   375  // DeveloperGenesisBlock returns the 'quickchain --dev' genesis block. Note, this must
   376  // be seeded with the
   377  func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
   378  	// Override the default period to the user requested one
   379  	config := *params.AllDPOSProtocolChanges
   380  	config.DPOS.Period = period
   381  
   382  	// Assemble and return the genesis with the precompiles and faucet pre-funded
   383  	return &Genesis{
   384  		Config:     &config,
   385  		ExtraData:  append(append(make([]byte, 32), faucet[:]...), make([]byte, 65)...),
   386  		GasLimit:   6283185,
   387  		Difficulty: big.NewInt(1),
   388  		Alloc: map[common.Address]GenesisAccount{
   389  			common.BytesToAddress([]byte{1}): {Balance: big.NewInt(1)}, // ECRecover
   390  			common.BytesToAddress([]byte{2}): {Balance: big.NewInt(1)}, // SHA256
   391  			common.BytesToAddress([]byte{3}): {Balance: big.NewInt(1)}, // RIPEMD
   392  			common.BytesToAddress([]byte{4}): {Balance: big.NewInt(1)}, // Identity
   393  			common.BytesToAddress([]byte{5}): {Balance: big.NewInt(1)}, // ModExp
   394  			common.BytesToAddress([]byte{6}): {Balance: big.NewInt(1)}, // ECAdd
   395  			common.BytesToAddress([]byte{7}): {Balance: big.NewInt(1)}, // ECScalarMul
   396  			common.BytesToAddress([]byte{8}): {Balance: big.NewInt(1)}, // ECPairing
   397  			faucet: {Balance: new(big.Int).Sub(new(big.Int).Lsh(big.NewInt(1), 256), big.NewInt(9))},
   398  		},
   399  	}
   400  }
   401  
   402  func decodePrealloc(data string) GenesisAlloc {
   403  	var p []struct{ Addr, Balance *big.Int }
   404  	if err := rlp.NewStream(strings.NewReader(data), 0).Decode(&p); err != nil {
   405  		panic(err)
   406  	}
   407  	ga := make(GenesisAlloc, len(p))
   408  	for _, account := range p {
   409  		ga[common.BigToAddress(account.Addr)] = GenesisAccount{Balance: account.Balance}
   410  	}
   411  	return ga
   412  }
   413  
   414  func initGenesisDposContext(g *Genesis, db qctdb.Database) *types.DposContext {
   415  	dc, err := types.NewDposContextFromProto(db, &types.DposContextProto{})
   416  	if err != nil {
   417  		log.Error("initGenesisDposContext", "dc", dc, "err", err)
   418  		return nil
   419  	}
   420  	if g.Config != nil && g.Config.DPOS != nil && g.Config.DPOS.Validators != nil {
   421  		dc.SetValidators(g.Config.DPOS.Validators)
   422  		var sa types.SortableAddresses
   423  		for _, v := range g.Config.DPOS.Validators {
   424  			sa = append(sa, &types.SortableAddress{Address: v, Weight: big.NewInt(0)})
   425  		}
   426  		dc.SetSortableAddresses(sa)
   427  		for _, validator := range g.Config.DPOS.Validators {
   428  			dc.DelegateTrie().TryUpdate(append(validator.Bytes(), validator.Bytes()...), validator.Bytes())
   429  			dc.SetCandidateContext(types.CandidateContext{
   430  				Addr:        validator,
   431  				State:       types.LoginState,
   432  				BlockNumber: big.NewInt(0),
   433  				Score:       big.NewInt(0),
   434  			})
   435  		}
   436  	}
   437  
   438  	if g.Config != nil && g.Config.DBFT != nil && g.Config.DBFT.Validators != nil {
   439  		log.Info("Writing default DBFT validators!")
   440  		dc.SetValidators(g.Config.DBFT.Validators)
   441  		var sa types.SortableAddresses
   442  		for _, v := range g.Config.DBFT.Validators {
   443  			sa = append(sa, &types.SortableAddress{Address: v, Weight: big.NewInt(0)})
   444  		}
   445  		dc.SetSortableAddresses(sa)
   446  		for _, validator := range g.Config.DBFT.Validators {
   447  			dc.DelegateTrie().TryUpdate(append(validator.Bytes(), validator.Bytes()...), validator.Bytes())
   448  			dc.SetCandidateContext(types.CandidateContext{
   449  				Addr:        validator,
   450  				State:       types.LoginState,
   451  				BlockNumber: big.NewInt(0),
   452  				Score:       big.NewInt(0),
   453  			})
   454  		}
   455  	}
   456  	return dc
   457  }