github.com/dominant-strategies/go-quai@v0.28.2/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  	"io/ioutil"
    26  	"math/big"
    27  	"os"
    28  
    29  	"github.com/dominant-strategies/go-quai/common"
    30  	"github.com/dominant-strategies/go-quai/common/hexutil"
    31  	"github.com/dominant-strategies/go-quai/common/math"
    32  	"github.com/dominant-strategies/go-quai/core/rawdb"
    33  	"github.com/dominant-strategies/go-quai/core/state"
    34  	"github.com/dominant-strategies/go-quai/core/types"
    35  	"github.com/dominant-strategies/go-quai/crypto"
    36  	"github.com/dominant-strategies/go-quai/ethdb"
    37  	"github.com/dominant-strategies/go-quai/log"
    38  	"github.com/dominant-strategies/go-quai/params"
    39  	"github.com/dominant-strategies/go-quai/trie"
    40  )
    41  
    42  //go:generate gencodec -type Genesis -field-override genesisSpecMarshaling -out gen_genesis.go
    43  //go:generate gencodec -type GenesisAccount -field-override genesisAccountMarshaling -out gen_genesis_account.go
    44  
    45  var errGenesisNoConfig = errors.New("genesis has no chain configuration")
    46  
    47  // Genesis specifies the header fields, state of a genesis block. It also defines hard
    48  // fork switch-over blocks through the chain configuration.
    49  type Genesis struct {
    50  	Config     *params.ChainConfig `json:"config"`
    51  	Nonce      uint64              `json:"nonce"`
    52  	Timestamp  uint64              `json:"timestamp"`
    53  	ExtraData  []byte              `json:"extraData"`
    54  	GasLimit   uint64              `json:"gasLimit"   gencodec:"required"`
    55  	Difficulty *big.Int            `json:"difficulty" gencodec:"required"`
    56  	Mixhash    common.Hash         `json:"mixHash"`
    57  	Coinbase   common.Address      `json:"coinbase"`
    58  
    59  	// These fields are used for consensus tests. Please don't use them
    60  	// in actual genesis blocks.
    61  	Number     []uint64      `json:"number"`
    62  	GasUsed    uint64        `json:"gasUsed"`
    63  	ParentHash []common.Hash `json:"parentHash"`
    64  	BaseFee    *big.Int      `json:"baseFeePerGas"`
    65  }
    66  
    67  // GenesisAlloc specifies the initial state that is part of the genesis block.
    68  type GenesisAlloc map[common.Address]GenesisAccount
    69  
    70  func (ga *GenesisAlloc) UnmarshalJSON(data []byte) error {
    71  	m := make(map[common.UnprefixedAddress]GenesisAccount)
    72  	if err := json.Unmarshal(data, &m); err != nil {
    73  		return err
    74  	}
    75  	*ga = make(GenesisAlloc)
    76  	for addr, a := range m {
    77  		internal := common.InternalAddress(addr)
    78  		(*ga)[common.NewAddressFromData(&internal)] = a
    79  	}
    80  	return nil
    81  }
    82  
    83  // GenesisAccount is an account in the state of the genesis block.
    84  type GenesisAccount struct {
    85  	Code       []byte                      `json:"code,omitempty"`
    86  	Storage    map[common.Hash]common.Hash `json:"storage,omitempty"`
    87  	Balance    *big.Int                    `json:"balance" gencodec:"required"`
    88  	Nonce      uint64                      `json:"nonce,omitempty"`
    89  	PrivateKey []byte                      `json:"secretKey,omitempty"` // for tests
    90  }
    91  
    92  // field type overrides for gencodec
    93  type genesisSpecMarshaling struct {
    94  	Nonce      math.HexOrDecimal64
    95  	Timestamp  math.HexOrDecimal64
    96  	ExtraData  hexutil.Bytes
    97  	GasLimit   math.HexOrDecimal64
    98  	GasUsed    math.HexOrDecimal64
    99  	Number     math.HexOrDecimal64
   100  	Difficulty *math.HexOrDecimal256
   101  	BaseFee    *math.HexOrDecimal256
   102  	Alloc      map[common.UnprefixedAddress]GenesisAccount
   103  }
   104  
   105  type genesisAccountMarshaling struct {
   106  	Code       hexutil.Bytes
   107  	Balance    *math.HexOrDecimal256
   108  	Nonce      math.HexOrDecimal64
   109  	Storage    map[storageJSON]storageJSON
   110  	PrivateKey hexutil.Bytes
   111  }
   112  
   113  // storageJSON represents a 256 bit byte array, but allows less than 256 bits when
   114  // unmarshaling from hex.
   115  type storageJSON common.Hash
   116  
   117  func (h *storageJSON) UnmarshalText(text []byte) error {
   118  	text = bytes.TrimPrefix(text, []byte("0x"))
   119  	if len(text) > 64 {
   120  		return fmt.Errorf("too many hex characters in storage key/value %q", text)
   121  	}
   122  	offset := len(h) - len(text)/2 // pad on the left
   123  	if _, err := hex.Decode(h[offset:], text); err != nil {
   124  		fmt.Println(err)
   125  		return fmt.Errorf("invalid hex storage key/value %q", text)
   126  	}
   127  	return nil
   128  }
   129  
   130  func (h storageJSON) MarshalText() ([]byte, error) {
   131  	return hexutil.Bytes(h[:]).MarshalText()
   132  }
   133  
   134  // GenesisMismatchError is raised when trying to overwrite an existing
   135  // genesis block with an incompatible one.
   136  type GenesisMismatchError struct {
   137  	Stored, New common.Hash
   138  }
   139  
   140  func (e *GenesisMismatchError) Error() string {
   141  	return fmt.Sprintf("database contains incompatible genesis (have %x, new %x)", e.Stored, e.New)
   142  }
   143  
   144  // SetupGenesisBlock writes or updates the genesis block in db.
   145  // The block that will be used is:
   146  //
   147  //	                     genesis == nil       genesis != nil
   148  //	                  +------------------------------------------
   149  //	db has no genesis |  main-net default  |  genesis
   150  //	db has genesis    |  from DB           |  genesis (if compatible)
   151  //
   152  // The stored chain configuration will be updated if it is compatible (i.e. does not
   153  // specify a fork block below the local head block). In case of a conflict, the
   154  // error is a *params.ConfigCompatError and the new, unwritten config is returned.
   155  //
   156  // The returned chain configuration is never nil.
   157  func SetupGenesisBlock(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
   158  	return SetupGenesisBlockWithOverride(db, genesis)
   159  }
   160  
   161  func SetupGenesisBlockWithOverride(db ethdb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, error) {
   162  	if genesis != nil && genesis.Config == nil {
   163  		return params.AllProgpowProtocolChanges, 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  		block, err := genesis.Commit(db)
   175  		if err != nil {
   176  			return genesis.Config, common.Hash{}, err
   177  		}
   178  		return genesis.Config, block.Hash(), nil
   179  	}
   180  	// We have the genesis block in database(perhaps in ancient database)
   181  	// but the corresponding state is missing.
   182  	header := rawdb.ReadHeader(db, stored, 0)
   183  	if _, err := state.New(header.Root(), state.NewDatabaseWithConfig(db, nil), nil); err != nil {
   184  		if genesis == nil {
   185  			genesis = DefaultGenesisBlock()
   186  		}
   187  		// Ensure the stored genesis matches with the given one.
   188  		hash := genesis.ToBlock(nil).Hash()
   189  		if hash != stored {
   190  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   191  		}
   192  		block, err := genesis.Commit(db)
   193  		if err != nil {
   194  			return genesis.Config, hash, err
   195  		}
   196  		return genesis.Config, block.Hash(), nil
   197  	}
   198  	// Check whether the genesis block is already written.
   199  	if genesis != nil {
   200  		hash := genesis.ToBlock(nil).Hash()
   201  		if hash != stored {
   202  			return genesis.Config, hash, &GenesisMismatchError{stored, hash}
   203  		}
   204  	}
   205  	// Get the existing chain configuration.
   206  	newcfg := genesis.configOrDefault(stored)
   207  	storedcfg := rawdb.ReadChainConfig(db, stored)
   208  	if storedcfg == nil {
   209  		log.Warn("Found genesis block without chain config")
   210  		rawdb.WriteChainConfig(db, stored, newcfg)
   211  		return newcfg, stored, nil
   212  	}
   213  	// Special case: don't change the existing config of a non-mainnet chain if no new
   214  	// config is supplied. These chains would get AllProtocolChanges (and a compat error)
   215  	// if we just continued here.
   216  	if genesis == nil && stored != params.ProgpowColosseumGenesisHash {
   217  		return storedcfg, stored, nil
   218  	}
   219  	// Check config compatibility and write the config. Compatibility errors
   220  	// are returned to the caller unless we're already at block zero.
   221  	height := rawdb.ReadHeaderNumber(db, rawdb.ReadHeadHeaderHash(db))
   222  	if height == nil {
   223  		return newcfg, stored, fmt.Errorf("missing block number for head header hash")
   224  	}
   225  
   226  	rawdb.WriteChainConfig(db, stored, newcfg)
   227  	return newcfg, stored, nil
   228  }
   229  
   230  func (g *Genesis) configOrDefault(ghash common.Hash) *params.ChainConfig {
   231  	switch {
   232  	case g != nil:
   233  		return g.Config
   234  	case ghash == params.ProgpowColosseumGenesisHash:
   235  		return params.ProgpowColosseumChainConfig
   236  	case ghash == params.ProgpowGardenGenesisHash:
   237  		return params.ProgpowGardenChainConfig
   238  	case ghash == params.ProgpowOrchardGenesisHash:
   239  		return params.ProgpowOrchardChainConfig
   240  	case ghash == params.ProgpowLighthouseGenesisHash:
   241  		return params.ProgpowLighthouseChainConfig
   242  	case ghash == params.ProgpowLocalGenesisHash:
   243  		return params.ProgpowLocalChainConfig
   244  	// Blake3 chain configs
   245  	case ghash == params.Blake3PowColosseumGenesisHash:
   246  		return params.Blake3PowColosseumChainConfig
   247  	case ghash == params.Blake3PowGardenGenesisHash:
   248  		return params.Blake3PowGardenChainConfig
   249  	case ghash == params.Blake3PowOrchardGenesisHash:
   250  		return params.Blake3PowOrchardChainConfig
   251  	case ghash == params.Blake3PowLighthouseGenesisHash:
   252  		return params.Blake3PowLighthouseChainConfig
   253  	case ghash == params.Blake3PowLocalGenesisHash:
   254  		return params.Blake3PowLocalChainConfig
   255  
   256  	default:
   257  		return params.AllProgpowProtocolChanges
   258  	}
   259  }
   260  
   261  // ToBlock creates the genesis block and writes state of a genesis specification
   262  // to the given database (or discards it if nil).
   263  func (g *Genesis) ToBlock(db ethdb.Database) *types.Block {
   264  	head := types.EmptyHeader()
   265  	head.SetNonce(types.EncodeNonce(g.Nonce))
   266  	head.SetTime(g.Timestamp)
   267  	head.SetExtra(g.ExtraData)
   268  	head.SetDifficulty(g.Difficulty)
   269  	head.SetCoinbase(common.ZeroAddr)
   270  	head.SetGasLimit(g.GasLimit)
   271  	head.SetGasUsed(0)
   272  	head.SetBaseFee(new(big.Int).SetUint64(params.InitialBaseFee))
   273  	if g.GasLimit == 0 {
   274  		head.SetGasLimit(params.GenesisGasLimit)
   275  	}
   276  	for i := 0; i < common.HierarchyDepth; i++ {
   277  		head.SetNumber(big.NewInt(0), i)
   278  		head.SetParentHash(common.Hash{}, i)
   279  	}
   280  
   281  	return types.NewBlock(head, nil, nil, nil, nil, nil, trie.NewStackTrie(nil))
   282  }
   283  
   284  // Commit writes the block and state of a genesis specification to the database.
   285  // The block is committed as the canonical head block.
   286  func (g *Genesis) Commit(db ethdb.Database) (*types.Block, error) {
   287  	block := g.ToBlock(db)
   288  	if block.Number().Sign() != 0 {
   289  		return nil, fmt.Errorf("can't commit genesis block with number > 0")
   290  	}
   291  	config := g.Config
   292  	if config == nil {
   293  		config = params.AllProgpowProtocolChanges
   294  	}
   295  	rawdb.WriteTermini(db, block.Hash(), types.EmptyTermini())
   296  	rawdb.WriteBlock(db, block)
   297  	rawdb.WriteReceipts(db, block.Hash(), block.NumberU64(), nil)
   298  	rawdb.WriteCanonicalHash(db, block.Hash(), block.NumberU64())
   299  	rawdb.WriteHeadBlockHash(db, block.Hash())
   300  	rawdb.WriteHeadHeaderHash(db, block.Hash())
   301  	rawdb.WriteChainConfig(db, block.Hash(), config)
   302  	return block, nil
   303  }
   304  
   305  // MustCommit writes the genesis block and state to db, panicking on error.
   306  // The block is committed as the canonical head block.
   307  func (g *Genesis) MustCommit(db ethdb.Database) *types.Block {
   308  	block, err := g.Commit(db)
   309  	if err != nil {
   310  		panic(err)
   311  	}
   312  	return block
   313  }
   314  
   315  // GenesisBlockForTesting creates and writes a block in which addr has the given wei balance.
   316  func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block {
   317  	g := Genesis{
   318  		BaseFee: big.NewInt(params.InitialBaseFee),
   319  	}
   320  	return g.MustCommit(db)
   321  }
   322  
   323  // DefaultGenesisBlock returns the Latest default Genesis block.
   324  // Currently it returns the DefaultColosseumGenesisBlock.
   325  func DefaultGenesisBlock() *Genesis {
   326  	return DefaultColosseumGenesisBlock("progpow")
   327  }
   328  
   329  // DefaultColosseumGenesisBlock returns the Quai Colosseum testnet genesis block.
   330  func DefaultColosseumGenesisBlock(consensusEngine string) *Genesis {
   331  	if consensusEngine == "blake3" {
   332  		return &Genesis{
   333  			Config:     params.Blake3PowColosseumChainConfig,
   334  			Nonce:      66,
   335  			ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"),
   336  			GasLimit:   5000000,
   337  			Difficulty: big.NewInt(2000000),
   338  		}
   339  	}
   340  	return &Genesis{
   341  		Config:     params.ProgpowColosseumChainConfig,
   342  		Nonce:      66,
   343  		ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"),
   344  		GasLimit:   5000000,
   345  		Difficulty: big.NewInt(1000000000),
   346  	}
   347  }
   348  
   349  // DefaultGardenGenesisBlock returns the Garden testnet genesis block.
   350  func DefaultGardenGenesisBlock(consensusEngine string) *Genesis {
   351  	if consensusEngine == "blake3" {
   352  		return &Genesis{
   353  			Config:     params.Blake3PowGardenChainConfig,
   354  			Nonce:      66,
   355  			ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa"),
   356  			GasLimit:   40000000,
   357  			Difficulty: big.NewInt(4000000),
   358  		}
   359  	}
   360  	return &Genesis{
   361  		Config:     params.ProgpowGardenChainConfig,
   362  		Nonce:      0,
   363  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353539"),
   364  		GasLimit:   5000000,
   365  		Difficulty: big.NewInt(300000000),
   366  	}
   367  }
   368  
   369  // DefaultOrchardGenesisBlock returns the Orchard testnet genesis block.
   370  func DefaultOrchardGenesisBlock(consensusEngine string) *Genesis {
   371  	if consensusEngine == "blake3" {
   372  		return &Genesis{
   373  			Config:     params.Blake3PowOrchardChainConfig,
   374  			Nonce:      66,
   375  			ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fc"),
   376  			GasLimit:   5000000,
   377  			Difficulty: big.NewInt(4000000),
   378  		}
   379  	}
   380  	return &Genesis{
   381  		Config:     params.ProgpowOrchardChainConfig,
   382  		Nonce:      0,
   383  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353536"),
   384  		GasLimit:   5000000,
   385  		Difficulty: big.NewInt(300000000),
   386  	}
   387  }
   388  
   389  // DefaultLighthouseGenesisBlock returns the Lighthouse testnet genesis block.
   390  func DefaultLighthouseGenesisBlock(consensusEngine string) *Genesis {
   391  	if consensusEngine == "blake3" {
   392  		return &Genesis{
   393  			Config:     params.Blake3PowLighthouseChainConfig,
   394  			Nonce:      66,
   395  			ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"),
   396  			GasLimit:   40000000,
   397  			Difficulty: big.NewInt(4000000),
   398  		}
   399  	}
   400  	return &Genesis{
   401  		Config:     params.ProgpowLighthouseChainConfig,
   402  		Nonce:      0,
   403  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353537"),
   404  		GasLimit:   5000000,
   405  		Difficulty: big.NewInt(300000000),
   406  	}
   407  }
   408  
   409  // DefaultLocalGenesisBlock returns the Local testnet genesis block.
   410  func DefaultLocalGenesisBlock(consensusEngine string) *Genesis {
   411  	if consensusEngine == "blake3" {
   412  		return &Genesis{
   413  			Config:     params.Blake3PowLocalChainConfig,
   414  			Nonce:      66,
   415  			ExtraData:  hexutil.MustDecode("0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fb"),
   416  			GasLimit:   5000000,
   417  			Difficulty: big.NewInt(300000),
   418  		}
   419  	}
   420  	return &Genesis{
   421  		Config:     params.ProgpowLocalChainConfig,
   422  		Nonce:      0,
   423  		ExtraData:  hexutil.MustDecode("0x3535353535353535353535353535353535353535353535353535353535353535"),
   424  		GasLimit:   5000000,
   425  		Difficulty: big.NewInt(1000),
   426  	}
   427  }
   428  
   429  // DeveloperGenesisBlock returns the 'quai --dev' genesis block.
   430  func DeveloperGenesisBlock(period uint64, faucet common.Address) *Genesis {
   431  	// Override the default period to the user requested one
   432  	config := *params.AllProgpowProtocolChanges
   433  	// Assemble and return the genesis with the precompiles and faucet pre-funded
   434  	return &Genesis{
   435  		Config:     &config,
   436  		ExtraData:  append(append(make([]byte, 32), faucet.Bytes()[:]...), make([]byte, crypto.SignatureLength)...),
   437  		GasLimit:   0x47b760,
   438  		BaseFee:    big.NewInt(params.InitialBaseFee),
   439  		Difficulty: big.NewInt(1),
   440  	}
   441  }
   442  
   443  func ReadGenesisAlloc(filename string) map[string]GenesisAccount {
   444  	jsonFile, err := os.Open(filename)
   445  	if err != nil {
   446  		log.Error(err.Error())
   447  		return nil
   448  	}
   449  	defer jsonFile.Close()
   450  	// Read the file contents
   451  	byteValue, err := ioutil.ReadAll(jsonFile)
   452  	if err != nil {
   453  		log.Error(err.Error())
   454  		return nil
   455  	}
   456  
   457  	// Parse the JSON data
   458  	var data map[string]GenesisAccount
   459  	err = json.Unmarshal(byteValue, &data)
   460  	if err != nil {
   461  		log.Error(err.Error())
   462  		return nil
   463  	}
   464  
   465  	// Use the parsed data
   466  	return data
   467  }