github.com/amazechain/amc@v0.1.3/params/config.go (about)

     1  // Copyright 2023 The AmazeChain Authors
     2  // This file is part of the AmazeChain library.
     3  //
     4  // The AmazeChain 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 AmazeChain 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 AmazeChain library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package params
    18  
    19  import (
    20  	"embed"
    21  	"encoding/binary"
    22  	"encoding/json"
    23  	"fmt"
    24  	"github.com/amazechain/amc/common/paths"
    25  	"github.com/amazechain/amc/common/types"
    26  	"github.com/amazechain/amc/internal/avm/common"
    27  	"github.com/amazechain/amc/params/networkname"
    28  	"golang.org/x/crypto/sha3"
    29  	"math/big"
    30  	"path"
    31  	"sort"
    32  	"strconv"
    33  )
    34  
    35  //go:embed chainspecs
    36  var chainspecs embed.FS
    37  
    38  func readChainSpec(filename string) *ChainConfig {
    39  	f, err := chainspecs.Open(filename)
    40  	if err != nil {
    41  		panic(fmt.Sprintf("Could not open chainspec for %s: %v", filename, err))
    42  	}
    43  	defer f.Close()
    44  	decoder := json.NewDecoder(f)
    45  	spec := &ChainConfig{}
    46  	err = decoder.Decode(&spec)
    47  	if err != nil {
    48  		panic(fmt.Sprintf("Could not parse chainspec for %s: %v", filename, err))
    49  	}
    50  	return spec
    51  }
    52  
    53  type ConsensusType string
    54  
    55  const (
    56  	AuRaConsensus   ConsensusType = "aura"
    57  	EtHashConsensus ConsensusType = "ethash"
    58  	CliqueConsensus ConsensusType = "clique"
    59  	ParliaConsensus ConsensusType = "parlia"
    60  	BorConsensus    ConsensusType = "bor"
    61  	AposConsensu    ConsensusType = "apos"
    62  	Faker           ConsensusType = "faker" // faker consensus
    63  )
    64  
    65  // Genesis hashes to enforce below configs on.
    66  var (
    67  	MainnetGenesisHash = types.HexToHash("0x138734b7044254e5ecbabf8056f5c2b73cd0847aaa5acac7345507cbeab387b8")
    68  	TestnetGenesisHash = types.HexToHash("0x5c0555d9ec963f58c63112862294e7e4836b12802304c23f2ec480a8f55cc5bb")
    69  )
    70  
    71  var (
    72  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    73  	MainnetChainConfig = readChainSpec("chainspecs/mainnet.json")
    74  
    75  	// TestnetChainConfig contains the chain parameters to run a node on the Test network.
    76  	TestnetChainConfig = readChainSpec("chainspecs/testnet.json")
    77  
    78  	TestChainConfig = &ChainConfig{
    79  		ChainID:               big.NewInt(1),
    80  		Consensus:             EtHashConsensus,
    81  		HomesteadBlock:        big.NewInt(0),
    82  		DAOForkBlock:          nil,
    83  		DAOForkSupport:        false,
    84  		TangerineWhistleBlock: big.NewInt(0),
    85  		TangerineWhistleHash:  types.Hash{},
    86  		SpuriousDragonBlock:   big.NewInt(0),
    87  		ByzantiumBlock:        big.NewInt(0),
    88  		ConstantinopleBlock:   big.NewInt(0),
    89  		PetersburgBlock:       big.NewInt(0),
    90  		IstanbulBlock:         big.NewInt(0),
    91  		MuirGlacierBlock:      big.NewInt(0),
    92  		BerlinBlock:           big.NewInt(0),
    93  		LondonBlock:           nil,
    94  		ArrowGlacierBlock:     nil,
    95  		Ethash:                new(EthashConfig),
    96  		Clique:                nil,
    97  	}
    98  )
    99  
   100  // ChainConfig is the core config which determines the blockchain settings.
   101  //
   102  // ChainConfig is stored in the database on a per block basis. This means
   103  // that any network, identified by its genesis block, can have its own
   104  // set of configuration options.
   105  type ChainConfig struct {
   106  	ChainName string
   107  	ChainID   *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   108  
   109  	Consensus ConsensusType `json:"consensus,omitempty"` // aura, ethash or clique
   110  
   111  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   112  
   113  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   114  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   115  
   116  	// Tangerine Whistle (EIP150) implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   117  	TangerineWhistleBlock *big.Int   `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   118  	TangerineWhistleHash  types.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   119  
   120  	SpuriousDragonBlock *big.Int `json:"eip155Block,omitempty"` // Spurious Dragon HF block
   121  
   122  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   123  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   124  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
   125  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
   126  	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // EIP-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
   127  	BerlinBlock         *big.Int `json:"berlinBlock,omitempty"`         // Berlin switch block (nil = no fork, 0 = already on berlin)
   128  	LondonBlock         *big.Int `json:"londonBlock,omitempty"`         // London switch block (nil = no fork, 0 = already on london)
   129  	ArrowGlacierBlock   *big.Int `json:"arrowGlacierBlock,omitempty"`   // EIP-4345 (bomb delay) switch block (nil = no fork, 0 = already activated)
   130  	GrayGlacierBlock    *big.Int `json:"grayGlacierBlock,omitempty"`    // EIP-5133 (bomb delay) switch block (nil = no fork, 0 = already activated)
   131  
   132  	// EIP-3675: Upgrade consensus to Proof-of-Stake
   133  	TerminalTotalDifficulty       *big.Int `json:"terminalTotalDifficulty,omitempty"`       // The merge happens when terminal total difficulty is reached
   134  	TerminalTotalDifficultyPassed bool     `json:"terminalTotalDifficultyPassed,omitempty"` // Disable PoW sync for networks that have already passed through the Merge
   135  	MergeNetsplitBlock            *big.Int `json:"mergeNetsplitBlock,omitempty"`            // Virtual fork after The Merge to use as a network splitter; see FORK_NEXT_VALUE in EIP-3675
   136  
   137  	ShanghaiBlock    *big.Int `json:"shanghaiBlock,omitempty"` // Shanghai switch block (nil = no fork, 0 = already activated)
   138  	CancunBlock      *big.Int `json:"cancunTime,omitempty"`
   139  	ShardingForkTime *big.Int `json:"shardingForkTime,omitempty"`
   140  	PragueTime       *big.Int `json:"pragueTime,omitempty"`
   141  
   142  	// Parlia fork blocks
   143  	//RamanujanBlock  *big.Int    `json:"ramanujanBlock,omitempty" toml:",omitempty"`  // ramanujanBlock switch block (nil = no fork, 0 = already activated)
   144  	//NielsBlock      *big.Int    `json:"nielsBlock,omitempty" toml:",omitempty"`      // nielsBlock switch block (nil = no fork, 0 = already activated)
   145  	//MirrorSyncBlock *big.Int    `json:"mirrorSyncBlock,omitempty" toml:",omitempty"` // mirrorSyncBlock switch block (nil = no fork, 0 = already activated)
   146  	//BrunoBlock      *big.Int    `json:"brunoBlock,omitempty" toml:",omitempty"`      // brunoBlock switch block (nil = no fork, 0 = already activated)
   147  	//EulerBlock      *big.Int    `json:"eulerBlock,omitempty" toml:",omitempty"`      // eulerBlock switch block (nil = no fork, 0 = already activated)
   148  	//GibbsBlock      *big.Int    `json:"gibbsBlock,omitempty" toml:",omitempty"`      // gibbsBlock switch block (nil = no fork, 0 = already activated)
   149  	NanoBlock    *big.Int `json:"nanoBlock,omitempty" toml:",omitempty"`    // nanoBlock switch block (nil = no fork, 0 = already activated)
   150  	MoranBlock   *big.Int `json:"moranBlock,omitempty" toml:",omitempty"`   // moranBlock switch block (nil = no fork, 0 = already activated)
   151  	BeijingBlock *big.Int `json:"beijingBlock,omitempty" toml:",omitempty"` // beijingBlock switch block (nil = no fork, 0 = already activated)
   152  	//Apos         *AposConfig `json:"apos,omitempty"`
   153  
   154  	// Gnosis Chain fork blocks
   155  	//PosdaoBlock *big.Int `json:"posdaoBlock,omitempty"`
   156  	//
   157  	Eip1559FeeCollector           *types.Address `json:"eip1559FeeCollector,omitempty"`           // (Optional) Address where burnt EIP-1559 fees go to
   158  	Eip1559FeeCollectorTransition *big.Int       `json:"eip1559FeeCollectorTransition,omitempty"` // (Optional) Block from which burnt EIP-1559 fees go to the Eip1559FeeCollector
   159  
   160  	// Various consensus engines
   161  	Ethash *EthashConfig `json:"ethash,omitempty"`
   162  	Clique *CliqueConfig `json:"clique,omitempty"`
   163  	Aura   *AuRaConfig   `json:"aura,omitempty"`
   164  	Parlia *ParliaConfig `json:"parlia,omitempty" toml:",omitempty"`
   165  	Bor    *BorConfig    `json:"bor,omitempty"`
   166  	Apos   *APosConfig   `json:"apos,omitempty"`
   167  }
   168  
   169  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   170  type EthashConfig struct{}
   171  
   172  // String implements the stringer interface, returning the consensus engine details.
   173  func (c *EthashConfig) String() string {
   174  	return "ethash"
   175  }
   176  
   177  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   178  type CliqueConfig struct {
   179  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   180  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   181  }
   182  
   183  // String implements the stringer interface, returning the consensus engine details.
   184  func (c *CliqueConfig) String() string {
   185  	return "clique"
   186  }
   187  
   188  type APosConfig struct {
   189  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   190  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   191  
   192  	RewardEpoch uint64   `json:"rewardEpoch"`
   193  	RewardLimit *big.Int `json:"rewardLimit"`
   194  
   195  	DepositContract     string `json:"depositContract"`     // Deposit contract
   196  	DepositNFTContract  string `json:"depositNFTContract"`  // Deposit NFT contract
   197  	DepositFUJIContract string `json:"depositFUJIContract"` // Deposit NFT contract
   198  }
   199  
   200  // String implements the stringer interface, returning the consensus engine details.
   201  func (b *APosConfig) String() string {
   202  	return fmt.Sprintf("{DepositContract: %v, NFTDepositContract:%v, Period: %v, Epoch: %v, RewardEpoch: %v, RewardLimit: %v}",
   203  		b.DepositContract,
   204  		b.DepositNFTContract,
   205  		b.Period,
   206  		b.Epoch,
   207  		b.RewardEpoch,
   208  		b.RewardLimit,
   209  	)
   210  }
   211  
   212  // AuRaConfig is the consensus engine configs for proof-of-authority based sealing.
   213  type AuRaConfig struct {
   214  	DBPath    string
   215  	InMemory  bool
   216  	Etherbase common.Address // same as miner etherbase
   217  }
   218  
   219  // String implements the stringer interface, returning the consensus engine details.
   220  func (c *AuRaConfig) String() string {
   221  	return "aura"
   222  }
   223  
   224  type ParliaConfig struct {
   225  	DBPath   string
   226  	InMemory bool
   227  	Period   uint64 `json:"period"` // Number of seconds between blocks to enforce
   228  	Epoch    uint64 `json:"epoch"`  // Epoch length to update validatorSet
   229  }
   230  
   231  // String implements the stringer interface, returning the consensus engine details.
   232  func (b *ParliaConfig) String() string {
   233  	return "parlia"
   234  }
   235  
   236  //type AposConfig struct {
   237  //	DepositContract string `json:"depositContract"` // Deposit contract
   238  //	Period          uint64 `json:"period"`          // Number of seconds between blocks to enforce
   239  //	Epoch           uint64 `json:"epoch"`           // Epoch length to reset votes and checkpoint
   240  //
   241  //	RewardEpoch uint64 `json:"rewardEpoch"`
   242  //	RewardLimit uint64 `json:"rewardLimit"`
   243  //}
   244  
   245  // BorConfig is the consensus engine configs for Matic bor based sealing.
   246  type BorConfig struct {
   247  	Period                map[string]uint64 `json:"period"`                // Number of seconds between blocks to enforce
   248  	ProducerDelay         uint64            `json:"producerDelay"`         // Number of seconds delay between two producer interval
   249  	Sprint                uint64            `json:"sprint"`                // Epoch length to proposer
   250  	BackupMultiplier      map[string]uint64 `json:"backupMultiplier"`      // Backup multiplier to determine the wiggle time
   251  	ValidatorContract     string            `json:"validatorContract"`     // Validator set contract
   252  	StateReceiverContract string            `json:"stateReceiverContract"` // State receiver contract
   253  
   254  	OverrideStateSyncRecords map[string]int         `json:"overrideStateSyncRecords"` // override state records count
   255  	BlockAlloc               map[string]interface{} `json:"blockAlloc"`
   256  	JaipurBlock              uint64                 `json:"jaipurBlock"` // Jaipur switch block (nil = no fork, 0 = already on jaipur)
   257  }
   258  
   259  // String implements the stringer interface, returning the consensus engine details.
   260  func (b *BorConfig) String() string {
   261  	return "bor"
   262  }
   263  
   264  func (c *BorConfig) CalculateBackupMultiplier(number uint64) uint64 {
   265  	return c.calculateBorConfigHelper(c.BackupMultiplier, number)
   266  }
   267  
   268  func (c *BorConfig) CalculatePeriod(number uint64) uint64 {
   269  	return c.calculateBorConfigHelper(c.Period, number)
   270  }
   271  
   272  func (c *BorConfig) IsJaipur(number uint64) bool {
   273  	return number >= c.JaipurBlock
   274  }
   275  
   276  func (c *BorConfig) calculateBorConfigHelper(field map[string]uint64, number uint64) uint64 {
   277  	keys := make([]string, 0, len(field))
   278  	for k := range field {
   279  		keys = append(keys, k)
   280  	}
   281  	sort.Strings(keys)
   282  	for i := 0; i < len(keys)-1; i++ {
   283  		valUint, _ := strconv.ParseUint(keys[i], 10, 64)
   284  		valUintNext, _ := strconv.ParseUint(keys[i+1], 10, 64)
   285  		if number > valUint && number < valUintNext {
   286  			return field[keys[i]]
   287  		}
   288  	}
   289  	return field[keys[len(keys)-1]]
   290  }
   291  
   292  // String implements the fmt.Stringer interface.
   293  func (c *ChainConfig) String() string {
   294  	return fmt.Sprintf("{ChainID: %v, Homestead: %v, DAO: %v, DAO Support: %v, Tangerine Whistle: %v, Spurious Dragon: %v, Byzantium: %v, Constantinople: %v, Petersburg: %v, Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Arrow Glacier: %v, Gray Glacier: %v, Terminal Total Difficulty: %v, Merge Netsplit: %v, Shanghai: %v, Cancun: %v}",
   295  		c.ChainID,
   296  		c.HomesteadBlock,
   297  		c.DAOForkBlock,
   298  		c.DAOForkSupport,
   299  		c.TangerineWhistleBlock,
   300  		c.SpuriousDragonBlock,
   301  		c.ByzantiumBlock,
   302  		c.ConstantinopleBlock,
   303  		c.PetersburgBlock,
   304  		c.IstanbulBlock,
   305  		c.MuirGlacierBlock,
   306  		c.BerlinBlock,
   307  		c.LondonBlock,
   308  		c.ArrowGlacierBlock,
   309  		c.GrayGlacierBlock,
   310  		c.TerminalTotalDifficulty,
   311  		c.MergeNetsplitBlock,
   312  		c.ShanghaiBlock,
   313  		c.CancunBlock,
   314  	)
   315  }
   316  
   317  func (c *ChainConfig) IsHeaderWithSeal() bool {
   318  	return c.Consensus == AuRaConsensus
   319  }
   320  
   321  type ConsensusSnapshotConfig struct {
   322  	CheckpointInterval uint64 // Number of blocks after which to save the vote snapshot to the database
   323  	InmemorySnapshots  int    // Number of recent vote snapshots to keep in memory
   324  	InmemorySignatures int    // Number of recent block signatures to keep in memory
   325  	DBPath             string
   326  	InMemory           bool
   327  }
   328  
   329  const cliquePath = "clique"
   330  
   331  func NewSnapshotConfig(checkpointInterval uint64, inmemorySnapshots int, inmemorySignatures int, inmemory bool, dbPath string) *ConsensusSnapshotConfig {
   332  	if len(dbPath) == 0 {
   333  		dbPath = paths.DefaultDataDir()
   334  	}
   335  
   336  	return &ConsensusSnapshotConfig{
   337  		checkpointInterval,
   338  		inmemorySnapshots,
   339  		inmemorySignatures,
   340  		path.Join(dbPath, cliquePath),
   341  		inmemory,
   342  	}
   343  }
   344  
   345  // NetworkNames are user friendly names to use in the chain spec banner.
   346  var NetworkNames = map[string]string{
   347  	"100100100": "testnet",
   348  	"94":        "mainnet",
   349  	//"131":       "testnet",
   350  }
   351  
   352  // Description returns a human-readable description of ChainConfig.
   353  func (c *ChainConfig) Description() string {
   354  	var banner string
   355  
   356  	// Create some basinc network config output
   357  	network := NetworkNames[c.ChainID.String()]
   358  	if network == "" {
   359  		network = "unknown"
   360  	}
   361  	banner += fmt.Sprintf("Chain ID:  %v (%s)\n", c.ChainID, network)
   362  
   363  	// Create a list of forks with a short description of them. Forks that only
   364  	// makes sense for mainnet should be optional at printing to avoid bloating
   365  	// the output for testnets and private networks.
   366  	//banner += fmt.Sprintf(" - Homestead:                   #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock)
   367  	//if c.DAOForkBlock != nil {
   368  	//	banner += fmt.Sprintf(" - DAO Fork:                    #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock)
   369  	//}
   370  	//banner += fmt.Sprintf(" - Tangerine Whistle (EIP 150): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)\n", c.TangerineWhistleBlock)
   371  	//banner += fmt.Sprintf(" - Spurious Dragon/1 (EIP 155): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.SpuriousDragonBlock)
   372  	//banner += fmt.Sprintf(" - Spurious Dragon/2 (EIP 158): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.SpuriousDragonBlock)
   373  	//banner += fmt.Sprintf(" - Byzantium:                   #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock)
   374  	//banner += fmt.Sprintf(" - Constantinople:              #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock)
   375  	//banner += fmt.Sprintf(" - Petersburg:                  #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock)
   376  	//banner += fmt.Sprintf(" - Istanbul:                    #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock)
   377  	//if c.MuirGlacierBlock != nil {
   378  	//	banner += fmt.Sprintf(" - Muir Glacier:                #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock)
   379  	//}
   380  	//banner += fmt.Sprintf(" - Berlin:                      #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)\n", c.BerlinBlock)
   381  	//banner += fmt.Sprintf(" - London:                      #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)\n", c.LondonBlock)
   382  	//if c.ArrowGlacierBlock != nil {
   383  	//	banner += fmt.Sprintf(" - Arrow Glacier:               #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)\n", c.ArrowGlacierBlock)
   384  	//}
   385  	//if c.GrayGlacierBlock != nil {
   386  	//	banner += fmt.Sprintf(" - Gray Glacier:                #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)\n", c.GrayGlacierBlock)
   387  	//}
   388  	banner += "\n"
   389  
   390  	// Add a special section for the merge as it's non-obvious
   391  	//if c.TerminalTotalDifficulty == nil {
   392  	//	banner += "The Merge is not yet available for this network!\n"
   393  	//	banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n"
   394  	//} else {
   395  	//	banner += "Merge configured:\n"
   396  	//	banner += " - Hard-fork specification:    https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n"
   397  	//	banner += fmt.Sprintf(" - Network known to be merged: %v\n", c.TerminalTotalDifficultyPassed)
   398  	//	banner += fmt.Sprintf(" - Total terminal difficulty:  %v\n", c.TerminalTotalDifficulty)
   399  	//	if c.MergeNetsplitBlock != nil {
   400  	//		banner += fmt.Sprintf(" - Merge netsplit block:       #%-8v\n", c.MergeNetsplitBlock)
   401  	//	}
   402  	//}
   403  	banner += "\n"
   404  
   405  	return banner
   406  }
   407  
   408  // IsHomestead returns whether num is either equal to the homestead block or greater.
   409  func (c *ChainConfig) IsHomestead(num uint64) bool {
   410  	return isForked(c.HomesteadBlock, num)
   411  }
   412  
   413  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   414  func (c *ChainConfig) IsDAOFork(num uint64) bool {
   415  	return isForked(c.DAOForkBlock, num)
   416  }
   417  
   418  // IsTangerineWhistle returns whether num is either equal to the Tangerine Whistle (EIP150) fork block or greater.
   419  func (c *ChainConfig) IsTangerineWhistle(num uint64) bool {
   420  	return isForked(c.TangerineWhistleBlock, num)
   421  }
   422  
   423  // IsSpuriousDragon returns whether num is either equal to the Spurious Dragon fork block or greater.
   424  func (c *ChainConfig) IsSpuriousDragon(num uint64) bool {
   425  	return isForked(c.SpuriousDragonBlock, num)
   426  }
   427  
   428  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   429  func (c *ChainConfig) IsByzantium(num uint64) bool {
   430  	return isForked(c.ByzantiumBlock, num)
   431  }
   432  
   433  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   434  func (c *ChainConfig) IsConstantinople(num uint64) bool {
   435  	return isForked(c.ConstantinopleBlock, num)
   436  }
   437  
   438  func (c *ChainConfig) IsMoran(num uint64) bool {
   439  	return isForked(c.MoranBlock, num)
   440  }
   441  
   442  //	func (c *ChainConfig) IsOnMoran(num *big.Int) bool {
   443  //		return configNumEqual(c.MoranBlock, num)
   444  //	}
   445  //
   446  // IsNano returns whether num is either equal to the euler fork block or greater.
   447  func (c *ChainConfig) IsNano(num uint64) bool {
   448  	return isForked(c.NanoBlock, num)
   449  }
   450  
   451  //
   452  //func (c *ChainConfig) IsOnNano(num *big.Int) bool {
   453  //	return configNumEqual(c.NanoBlock, num)
   454  //}
   455  
   456  // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
   457  func (c *ChainConfig) IsMuirGlacier(num uint64) bool {
   458  	return isForked(c.MuirGlacierBlock, num)
   459  }
   460  
   461  // IsPetersburg returns whether num is either
   462  // - equal to or greater than the PetersburgBlock fork block,
   463  // - OR is nil, and Constantinople is active
   464  func (c *ChainConfig) IsPetersburg(num uint64) bool {
   465  	return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num)
   466  }
   467  
   468  // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater.
   469  func (c *ChainConfig) IsIstanbul(num uint64) bool {
   470  	return isForked(c.IstanbulBlock, num)
   471  }
   472  
   473  // IsBerlin returns whether num is either equal to the Berlin fork block or greater.
   474  func (c *ChainConfig) IsBerlin(num uint64) bool {
   475  	return isForked(c.BerlinBlock, num)
   476  }
   477  
   478  // IsLondon returns whether num is either equal to the London fork block or greater.
   479  func (c *ChainConfig) IsLondon(num uint64) bool {
   480  	return isForked(c.LondonBlock, num)
   481  }
   482  
   483  // IsArrowGlacier returns whether num is either equal to the Arrow Glacier (EIP-4345) fork block or greater.
   484  func (c *ChainConfig) IsArrowGlacier(num uint64) bool {
   485  	return isForked(c.ArrowGlacierBlock, num)
   486  }
   487  
   488  // IsGrayGlacier returns whether num is either equal to the Gray Glacier (EIP-5133) fork block or greater.
   489  func (c *ChainConfig) IsGrayGlacier(num uint64) bool {
   490  	return isForked(c.GrayGlacierBlock, num)
   491  }
   492  
   493  // IsShanghai returns whether num is either equal to the Shanghai fork block or greater.
   494  func (c *ChainConfig) IsShanghai(num uint64) bool {
   495  	return isForked(c.ShanghaiBlock, num)
   496  }
   497  
   498  // IsCancun returns whether num is either equal to the Cancun fork block or greater.
   499  func (c *ChainConfig) IsCancun(num uint64) bool {
   500  	return isForked(c.CancunBlock, num)
   501  }
   502  
   503  // IsPrague returns whether time is either equal to the Prague fork time or greater.
   504  func (c *ChainConfig) IsPrague(time uint64) bool {
   505  	return isForked(c.PragueTime, time)
   506  }
   507  
   508  // IsBeijing returns whether num is either equal to the IsBeijing fork block or greater.
   509  func (c *ChainConfig) IsBeijing(num uint64) bool {
   510  	return isForked(c.BeijingBlock, num)
   511  }
   512  
   513  func (c *ChainConfig) IsEip1559FeeCollector(num uint64) bool {
   514  	return c.Eip1559FeeCollector != nil && isForked(c.Eip1559FeeCollectorTransition, num)
   515  }
   516  
   517  //func (c *ChainConfig) IsMoran(num uint64) bool {
   518  //	return isForked(c.MoranBlock, num)
   519  //}
   520  //
   521  //func (c *ChainConfig) IsOnMoran(num *big.Int) bool {
   522  //	return numEqual(c.MoranBlock, num)
   523  //}
   524  //
   525  //// IsNano returns whether num is either equal to the euler fork block or greater.
   526  //func (c *ChainConfig) IsNano(num uint64) bool {
   527  //	return isForked(c.NanoBlock, num)
   528  //}
   529  
   530  // CheckCompatible checks whether scheduled fork transitions have been imported
   531  // with a mismatching chain configuration.
   532  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   533  	bhead := height
   534  
   535  	// Iterate checkCompatible to find the lowest conflict.
   536  	var lasterr *ConfigCompatError
   537  	for {
   538  		err := c.checkCompatible(newcfg, bhead)
   539  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   540  			break
   541  		}
   542  		lasterr = err
   543  		bhead = err.RewindTo
   544  	}
   545  	return lasterr
   546  }
   547  
   548  // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
   549  // to guarantee that forks can be implemented in a different order than on official networks
   550  func (c *ChainConfig) CheckConfigForkOrder() error {
   551  	if c != nil && c.ChainID != nil && c.ChainID.Uint64() == 77 {
   552  		return nil
   553  	}
   554  	type fork struct {
   555  		name     string
   556  		block    *big.Int
   557  		optional bool // if true, the fork may be nil and next fork is still allowed
   558  	}
   559  	var lastFork fork
   560  	for _, cur := range []fork{
   561  		{name: "homesteadBlock", block: c.HomesteadBlock},
   562  		{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
   563  		{name: "eip150Block", block: c.TangerineWhistleBlock},
   564  		{name: "eip155Block", block: c.SpuriousDragonBlock},
   565  		{name: "byzantiumBlock", block: c.ByzantiumBlock},
   566  		{name: "constantinopleBlock", block: c.ConstantinopleBlock},
   567  		{name: "petersburgBlock", block: c.PetersburgBlock},
   568  		{name: "istanbulBlock", block: c.IstanbulBlock},
   569  		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
   570  		//{name: "eulerBlock", block: c.EulerBlock, optional: true},
   571  		//{name: "gibbsBlock", block: c.GibbsBlock, optional: true},
   572  		{name: "berlinBlock", block: c.BerlinBlock},
   573  		{name: "londonBlock", block: c.LondonBlock},
   574  		{name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true},
   575  		{name: "grayGlacierBlock", block: c.GrayGlacierBlock, optional: true},
   576  		{name: "mergeNetsplitBlock", block: c.MergeNetsplitBlock, optional: true},
   577  		{name: "shanghaiBlock", block: c.ShanghaiBlock},
   578  		{name: "cancunBlock", block: c.CancunBlock},
   579  	} {
   580  		if lastFork.name != "" {
   581  			// Next one must be higher number
   582  			if lastFork.block == nil && cur.block != nil {
   583  				return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
   584  					lastFork.name, cur.name, cur.block)
   585  			}
   586  			if lastFork.block != nil && cur.block != nil {
   587  				if lastFork.block.Cmp(cur.block) > 0 {
   588  					return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
   589  						lastFork.name, lastFork.block, cur.name, cur.block)
   590  				}
   591  			}
   592  			// If it was optional and not set, then ignore it
   593  		}
   594  		if !cur.optional || cur.block != nil {
   595  			lastFork = cur
   596  		}
   597  	}
   598  	return nil
   599  }
   600  
   601  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head uint64) *ConfigCompatError {
   602  	// Ethereum mainnet forks
   603  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   604  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   605  	}
   606  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   607  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   608  	}
   609  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   610  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   611  	}
   612  	if isForkIncompatible(c.TangerineWhistleBlock, newcfg.TangerineWhistleBlock, head) {
   613  		return newCompatError("Tangerine Whistle fork block", c.TangerineWhistleBlock, newcfg.TangerineWhistleBlock)
   614  	}
   615  	if isForkIncompatible(c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock, head) {
   616  		return newCompatError("Spurious Dragon fork block", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock)
   617  	}
   618  	if c.IsSpuriousDragon(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   619  		return newCompatError("EIP155 chain ID", c.SpuriousDragonBlock, newcfg.SpuriousDragonBlock)
   620  	}
   621  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   622  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   623  	}
   624  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   625  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   626  	}
   627  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) {
   628  		// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
   629  		// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
   630  		if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) {
   631  			return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   632  		}
   633  	}
   634  	if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) {
   635  		return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   636  	}
   637  	if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) {
   638  		return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
   639  	}
   640  	if isForkIncompatible(c.BerlinBlock, newcfg.BerlinBlock, head) {
   641  		return newCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock)
   642  	}
   643  	if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) {
   644  		return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock)
   645  	}
   646  	if isForkIncompatible(c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock, head) {
   647  		return newCompatError("Arrow Glacier fork block", c.ArrowGlacierBlock, newcfg.ArrowGlacierBlock)
   648  	}
   649  	if isForkIncompatible(c.GrayGlacierBlock, newcfg.GrayGlacierBlock, head) {
   650  		return newCompatError("Gray Glacier fork block", c.GrayGlacierBlock, newcfg.GrayGlacierBlock)
   651  	}
   652  	if isForkIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, head) {
   653  		return newCompatError("Merge netsplit block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock)
   654  	}
   655  	if isForkIncompatible(c.ShanghaiBlock, newcfg.ShanghaiBlock, head) {
   656  		return newCompatError("Shanghai fork block", c.ShanghaiBlock, newcfg.ShanghaiBlock)
   657  	}
   658  	if isForkIncompatible(c.CancunBlock, newcfg.CancunBlock, head) {
   659  		return newCompatError("Cancun fork block", c.CancunBlock, newcfg.CancunBlock)
   660  	}
   661  
   662  	// Parlia forks
   663  	//if isForkIncompatible(c.RamanujanBlock, newcfg.RamanujanBlock, head) {
   664  	//	return newCompatError("Ramanujan fork block", c.RamanujanBlock, newcfg.RamanujanBlock)
   665  	//}
   666  	//if isForkIncompatible(c.NielsBlock, newcfg.NielsBlock, head) {
   667  	//	return newCompatError("Niels fork block", c.NielsBlock, newcfg.NielsBlock)
   668  	//}
   669  	//if isForkIncompatible(c.MirrorSyncBlock, newcfg.MirrorSyncBlock, head) {
   670  	//	return newCompatError("MirrorSync fork block", c.MirrorSyncBlock, newcfg.MirrorSyncBlock)
   671  	//}
   672  	//if isForkIncompatible(c.BrunoBlock, newcfg.BrunoBlock, head) {
   673  	//	return newCompatError("Bruno fork block", c.BrunoBlock, newcfg.BrunoBlock)
   674  	//}
   675  	//if isForkIncompatible(c.EulerBlock, newcfg.EulerBlock, head) {
   676  	//	return newCompatError("Euler fork block", c.EulerBlock, newcfg.EulerBlock)
   677  	//}
   678  	//if isForkIncompatible(c.GibbsBlock, newcfg.GibbsBlock, head) {
   679  	//	return newCompatError("Gibbs fork block", c.GibbsBlock, newcfg.GibbsBlock)
   680  	//}
   681  	//if isForkIncompatible(c.NanoBlock, newcfg.NanoBlock, head) {
   682  	//	return newCompatError("Nano fork block", c.NanoBlock, newcfg.NanoBlock)
   683  	//}
   684  	//if isForkIncompatible(c.MoranBlock, newcfg.MoranBlock, head) {
   685  	//	return newCompatError("moran fork block", c.MoranBlock, newcfg.MoranBlock)
   686  	//}
   687  	return nil
   688  }
   689  
   690  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   691  // block s2 because head is already past the fork.
   692  func isForkIncompatible(s1, s2 *big.Int, head uint64) bool {
   693  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   694  }
   695  
   696  // isForked returns whether a fork scheduled at block s is active at the given head block.
   697  func isForked(s *big.Int, head uint64) bool {
   698  	if s == nil {
   699  		return false
   700  	}
   701  	return s.Uint64() <= head
   702  }
   703  
   704  func configNumEqual(x, y *big.Int) bool {
   705  	if x == nil {
   706  		return y == nil
   707  	}
   708  	if y == nil {
   709  		return x == nil
   710  	}
   711  	return x.Cmp(y) == 0
   712  }
   713  
   714  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   715  // ChainConfig that would alter the past.
   716  type ConfigCompatError struct {
   717  	What string
   718  	// block numbers of the stored and new configurations
   719  	StoredConfig, NewConfig *big.Int
   720  	// the block number to which the local chain must be rewound to correct the error
   721  	RewindTo uint64
   722  }
   723  
   724  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   725  	var rew *big.Int
   726  	switch {
   727  	case storedblock == nil:
   728  		rew = newblock
   729  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   730  		rew = storedblock
   731  	default:
   732  		rew = newblock
   733  	}
   734  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   735  	if rew != nil && rew.Sign() > 0 {
   736  		err.RewindTo = rew.Uint64() - 1
   737  	}
   738  	return err
   739  }
   740  
   741  func (err *ConfigCompatError) Error() string {
   742  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   743  }
   744  
   745  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   746  // that do not have or require information about the block.
   747  //
   748  // Rules is a one time interface meaning that it shouldn't be used in between transition
   749  // phases.
   750  type Rules struct {
   751  	ChainID                                                 *big.Int
   752  	IsHomestead, IsTangerineWhistle, IsSpuriousDragon       bool
   753  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
   754  	IsBerlin, IsLondon, IsShanghai, IsCancun, IsPrague      bool
   755  	IsNano, IsMoran                                         bool
   756  	IsEip1559FeeCollector                                   bool
   757  	IsParlia, IsStarknet, IsAura, IsBeijing                 bool
   758  }
   759  
   760  // Rules ensures c's ChainID is not nil.
   761  func (c *ChainConfig) Rules(num uint64) *Rules {
   762  	chainID := c.ChainID
   763  	if chainID == nil {
   764  		chainID = new(big.Int)
   765  	}
   766  	return &Rules{
   767  		ChainID:               new(big.Int).Set(chainID),
   768  		IsHomestead:           c.IsHomestead(num),
   769  		IsTangerineWhistle:    c.IsTangerineWhistle(num),
   770  		IsSpuriousDragon:      c.IsSpuriousDragon(num),
   771  		IsByzantium:           c.IsByzantium(num),
   772  		IsConstantinople:      c.IsConstantinople(num),
   773  		IsPetersburg:          c.IsPetersburg(num),
   774  		IsIstanbul:            c.IsIstanbul(num),
   775  		IsBerlin:              c.IsBerlin(num),
   776  		IsLondon:              c.IsLondon(num),
   777  		IsShanghai:            c.IsShanghai(num),
   778  		IsCancun:              c.IsCancun(num),
   779  		IsPrague:              c.IsPrague(num),
   780  		IsNano:                c.IsNano(num),
   781  		IsMoran:               c.IsMoran(num),
   782  		IsEip1559FeeCollector: c.IsEip1559FeeCollector(num),
   783  		IsParlia:              c.Parlia != nil,
   784  		IsAura:                c.Aura != nil,
   785  		IsBeijing:             c.IsBeijing(num),
   786  	}
   787  }
   788  
   789  func ChainConfigByChainName(chain string) *ChainConfig {
   790  	switch chain {
   791  	case networkname.MainnetChainName:
   792  		return MainnetChainConfig
   793  	case networkname.TestnetChainName:
   794  		return TestnetChainConfig
   795  	default:
   796  		return nil
   797  	}
   798  }
   799  
   800  func GenesisHashByChainName(chain string) *types.Hash {
   801  	switch chain {
   802  	case networkname.MainnetChainName:
   803  		return &MainnetGenesisHash
   804  	case networkname.TestnetChainName:
   805  		return &TestnetGenesisHash
   806  	default:
   807  		return nil
   808  	}
   809  }
   810  
   811  func ChainConfigByGenesisHash(genesisHash types.Hash) *ChainConfig {
   812  	switch {
   813  	case genesisHash == MainnetGenesisHash:
   814  		return MainnetChainConfig
   815  	case genesisHash == TestnetGenesisHash:
   816  		return TestnetChainConfig
   817  	default:
   818  		return nil
   819  	}
   820  }
   821  
   822  func NetworkIDByChainName(chain string) uint64 {
   823  	switch chain {
   824  	case networkname.MainnetChainName:
   825  		return 97
   826  	case networkname.TestnetChainName:
   827  		return 100100100
   828  	default:
   829  		config := ChainConfigByChainName(chain)
   830  		if config == nil {
   831  			return 0
   832  		}
   833  		return config.ChainID.Uint64()
   834  	}
   835  }
   836  
   837  // TrustedCheckpoint represents a set of post-processed trie roots (CHT and
   838  // BloomTrie) associated with the appropriate section index and head hash. It is
   839  // used to start light syncing from this checkpoint and avoid downloading the
   840  // entire header chain while still being able to securely access old headers/logs.
   841  type TrustedCheckpoint struct {
   842  	SectionIndex uint64     `json:"sectionIndex"`
   843  	SectionHead  types.Hash `json:"sectionHead"`
   844  	CHTRoot      types.Hash `json:"chtRoot"`
   845  	BloomRoot    types.Hash `json:"bloomRoot"`
   846  }
   847  
   848  // HashEqual returns an indicator comparing the itself hash with given one.
   849  func (c *TrustedCheckpoint) HashEqual(hash types.Hash) bool {
   850  	if c.Empty() {
   851  		return hash == types.Hash{}
   852  	}
   853  	return c.Hash() == hash
   854  }
   855  
   856  // Hash returns the hash of checkpoint's four key fields(index, sectionHead, chtRoot and bloomTrieRoot).
   857  func (c *TrustedCheckpoint) Hash() types.Hash {
   858  	var sectionIndex [8]byte
   859  	binary.BigEndian.PutUint64(sectionIndex[:], c.SectionIndex)
   860  
   861  	w := sha3.NewLegacyKeccak256()
   862  	w.Write(sectionIndex[:])
   863  	w.Write(c.SectionHead[:])
   864  	w.Write(c.CHTRoot[:])
   865  	w.Write(c.BloomRoot[:])
   866  
   867  	var h types.Hash
   868  	w.Sum(h[:0])
   869  	return h
   870  }
   871  
   872  // Empty returns an indicator whether the checkpoint is regarded as empty.
   873  func (c *TrustedCheckpoint) Empty() bool {
   874  	return c.SectionHead == (types.Hash{}) || c.CHTRoot == (types.Hash{}) || c.BloomRoot == (types.Hash{})
   875  }
   876  
   877  // CheckpointOracleConfig represents a set of checkpoint contract(which acts as an oracle)
   878  // blockchain which used for light client checkpoint syncing.
   879  type CheckpointOracleConfig struct {
   880  	Address   types.Address   `json:"address"`
   881  	Signers   []types.Address `json:"signers"`
   882  	Threshold uint64          `json:"threshold"`
   883  }