github.com/core-coin/go-core/v2@v2.1.9/core/genesis.go (about)

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