github.com/aidoskuneen/adk-node@v0.0.0-20220315131952-2e32567cb7f4/params/config.go (about)

     1  // Copyright 2021 The adkgo Authors
     2  // This file is part of the adkgo library (adapted for adkgo from go--ethereum v1.10.8).
     3  //
     4  // the adkgo 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 adkgo 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 adkgo library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package params
    18  
    19  import (
    20  	"encoding/binary"
    21  	"fmt"
    22  	"math/big"
    23  
    24  	"github.com/aidoskuneen/adk-node/common"
    25  	"golang.org/x/crypto/sha3"
    26  )
    27  
    28  // Genesis hashes to enforce below configs on.
    29  var (
    30  	MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
    31  	RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
    32  	RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
    33  	GoerliGenesisHash  = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
    34  )
    35  
    36  // TrustedCheckpoints associates each known checkpoint with the genesis hash of
    37  // the chain it belongs to.
    38  var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{
    39  	MainnetGenesisHash: MainnetTrustedCheckpoint,
    40  	RopstenGenesisHash: RopstenTrustedCheckpoint,
    41  	RinkebyGenesisHash: RinkebyTrustedCheckpoint,
    42  	GoerliGenesisHash:  GoerliTrustedCheckpoint,
    43  }
    44  
    45  // CheckpointOracles associates each known checkpoint oracles with the genesis hash of
    46  // the chain it belongs to.
    47  var CheckpointOracles = map[common.Hash]*CheckpointOracleConfig{
    48  	MainnetGenesisHash: MainnetCheckpointOracle,
    49  	RopstenGenesisHash: RopstenCheckpointOracle,
    50  	RinkebyGenesisHash: RinkebyCheckpointOracle,
    51  	GoerliGenesisHash:  GoerliCheckpointOracle,
    52  }
    53  
    54  var (
    55  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    56  	MainnetChainConfig = &ChainConfig{
    57  		ChainID:             big.NewInt(1),
    58  		HomesteadBlock:      big.NewInt(1_150_000),
    59  		DAOForkBlock:        big.NewInt(1_920_000),
    60  		DAOForkSupport:      true,
    61  		EIP150Block:         big.NewInt(2_463_000),
    62  		EIP150Hash:          common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    63  		EIP155Block:         big.NewInt(2_675_000),
    64  		EIP158Block:         big.NewInt(2_675_000),
    65  		ByzantiumBlock:      big.NewInt(4_370_000),
    66  		ConstantinopleBlock: big.NewInt(7_280_000),
    67  		PetersburgBlock:     big.NewInt(7_280_000),
    68  		IstanbulBlock:       big.NewInt(9_069_000),
    69  		MuirGlacierBlock:    big.NewInt(9_200_000),
    70  		BerlinBlock:         big.NewInt(12_244_000),
    71  		LondonBlock:         big.NewInt(12_965_000),
    72  		Ethash:              new(EthashConfig),
    73  	}
    74  
    75  	// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
    76  	MainnetTrustedCheckpoint = &TrustedCheckpoint{
    77  		SectionIndex: 395,
    78  		SectionHead:  common.HexToHash("0xbfca95b8c1de014e252288e9c32029825fadbff58285f5b54556525e480dbb5b"),
    79  		CHTRoot:      common.HexToHash("0x2ccf3dbb58eb6375e037fdd981ca5778359e4b8fa0270c2878b14361e64161e7"),
    80  		BloomRoot:    common.HexToHash("0x2d46ec65a6941a2dc1e682f8f81f3d24192021f492fdf6ef0fdd51acb0f4ba0f"),
    81  	}
    82  
    83  	// MainnetCheckpointOracle contains a set of configs for the main network oracle.
    84  	MainnetCheckpointOracle = &CheckpointOracleConfig{
    85  		Address: common.HexToAddress("0x9a9070028361F7AAbeB3f2F2Dc07F82C4a98A02a"),
    86  		Signers: []common.Address{
    87  			common.HexToAddress("0x1b2C260efc720BE89101890E4Db589b44E950527"), // Peter
    88  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
    89  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
    90  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
    91  			common.HexToAddress("0x0DF8fa387C602AE62559cC4aFa4972A7045d6707"), // Guillaume
    92  		},
    93  		Threshold: 2,
    94  	}
    95  
    96  	// RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network.
    97  	RopstenChainConfig = &ChainConfig{
    98  		ChainID:             big.NewInt(3),
    99  		HomesteadBlock:      big.NewInt(0),
   100  		DAOForkBlock:        nil,
   101  		DAOForkSupport:      true,
   102  		EIP150Block:         big.NewInt(0),
   103  		EIP150Hash:          common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
   104  		EIP155Block:         big.NewInt(10),
   105  		EIP158Block:         big.NewInt(10),
   106  		ByzantiumBlock:      big.NewInt(1_700_000),
   107  		ConstantinopleBlock: big.NewInt(4_230_000),
   108  		PetersburgBlock:     big.NewInt(4_939_394),
   109  		IstanbulBlock:       big.NewInt(6_485_846),
   110  		MuirGlacierBlock:    big.NewInt(7_117_117),
   111  		BerlinBlock:         big.NewInt(9_812_189),
   112  		LondonBlock:         big.NewInt(10_499_401),
   113  		Ethash:              new(EthashConfig),
   114  	}
   115  
   116  	// RopstenTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
   117  	RopstenTrustedCheckpoint = &TrustedCheckpoint{
   118  		SectionIndex: 329,
   119  		SectionHead:  common.HexToHash("0xe66f7038333a01fb95dc9ea03e5a2bdaf4b833cdcb9e393b9127e013bd64d39b"),
   120  		CHTRoot:      common.HexToHash("0x1b0c883338ac0d032122800c155a2e73105fbfebfaa50436893282bc2d9feec5"),
   121  		BloomRoot:    common.HexToHash("0x3cc98c88d283bf002378246f22c653007655cbcea6ed89f98d739f73bd341a01"),
   122  	}
   123  
   124  	// RopstenCheckpointOracle contains a set of configs for the Ropsten test network oracle.
   125  	RopstenCheckpointOracle = &CheckpointOracleConfig{
   126  		Address: common.HexToAddress("0xEF79475013f154E6A65b54cB2742867791bf0B84"),
   127  		Signers: []common.Address{
   128  			common.HexToAddress("0x32162F3581E88a5f62e8A61892B42C46E2c18f7b"), // Peter
   129  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
   130  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
   131  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
   132  			common.HexToAddress("0x0DF8fa387C602AE62559cC4aFa4972A7045d6707"), // Guillaume
   133  		},
   134  		Threshold: 2,
   135  	}
   136  
   137  	// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
   138  	RinkebyChainConfig = &ChainConfig{
   139  		ChainID:             big.NewInt(4),
   140  		HomesteadBlock:      big.NewInt(1),
   141  		DAOForkBlock:        nil,
   142  		DAOForkSupport:      true,
   143  		EIP150Block:         big.NewInt(2),
   144  		EIP150Hash:          common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
   145  		EIP155Block:         big.NewInt(3),
   146  		EIP158Block:         big.NewInt(3),
   147  		ByzantiumBlock:      big.NewInt(1_035_301),
   148  		ConstantinopleBlock: big.NewInt(3_660_663),
   149  		PetersburgBlock:     big.NewInt(4_321_234),
   150  		IstanbulBlock:       big.NewInt(5_435_345),
   151  		MuirGlacierBlock:    nil,
   152  		BerlinBlock:         big.NewInt(8_290_928),
   153  		LondonBlock:         big.NewInt(8_897_988),
   154  		Clique: &CliqueConfig{
   155  			Period: 15,
   156  			Epoch:  30000,
   157  		},
   158  	}
   159  
   160  	// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
   161  	RinkebyTrustedCheckpoint = &TrustedCheckpoint{
   162  		SectionIndex: 276,
   163  		SectionHead:  common.HexToHash("0xea89a4b04e3da9bd688e316f8de669396b6d4a38a19d2cd96a00b70d58b836aa"),
   164  		CHTRoot:      common.HexToHash("0xd6889d0bf6673c0d2c1cf6e9098a6fe5b30888a115b6112796aa8ee8efc4a723"),
   165  		BloomRoot:    common.HexToHash("0x6009a9256b34b8bde3a3f094afb647ba5d73237546017b9025d64ac1ff54c47c"),
   166  	}
   167  
   168  	// RinkebyCheckpointOracle contains a set of configs for the Rinkeby test network oracle.
   169  	RinkebyCheckpointOracle = &CheckpointOracleConfig{
   170  		Address: common.HexToAddress("0xebe8eFA441B9302A0d7eaECc277c09d20D684540"),
   171  		Signers: []common.Address{
   172  			common.HexToAddress("0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3"), // Peter
   173  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
   174  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
   175  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
   176  		},
   177  		Threshold: 2,
   178  	}
   179  
   180  	// GoerliChainConfig contains the chain parameters to run a node on the Görli test network.
   181  	GoerliChainConfig = &ChainConfig{
   182  		ChainID:             big.NewInt(5),
   183  		HomesteadBlock:      big.NewInt(0),
   184  		DAOForkBlock:        nil,
   185  		DAOForkSupport:      true,
   186  		EIP150Block:         big.NewInt(0),
   187  		EIP155Block:         big.NewInt(0),
   188  		EIP158Block:         big.NewInt(0),
   189  		ByzantiumBlock:      big.NewInt(0),
   190  		ConstantinopleBlock: big.NewInt(0),
   191  		PetersburgBlock:     big.NewInt(0),
   192  		IstanbulBlock:       big.NewInt(1_561_651),
   193  		MuirGlacierBlock:    nil,
   194  		BerlinBlock:         big.NewInt(4_460_644),
   195  		LondonBlock:         big.NewInt(5_062_605),
   196  		Clique: &CliqueConfig{
   197  			Period: 15,
   198  			Epoch:  30000,
   199  		},
   200  	}
   201  
   202  	// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
   203  	GoerliTrustedCheckpoint = &TrustedCheckpoint{
   204  		SectionIndex: 160,
   205  		SectionHead:  common.HexToHash("0xb5a666c790dc35a5613d04ebba8ba47a850b45a15d9b95ad7745c35ae034b5a5"),
   206  		CHTRoot:      common.HexToHash("0x6b4e00df52bdc38fa6c26c8ef595c2ad6184963ea36ab08ee744af460aa735e1"),
   207  		BloomRoot:    common.HexToHash("0x8fa88f5e50190cb25243aeee262a1a9e4434a06f8d455885dcc1b5fc48c33836"),
   208  	}
   209  
   210  	// GoerliCheckpointOracle contains a set of configs for the Goerli test network oracle.
   211  	GoerliCheckpointOracle = &CheckpointOracleConfig{
   212  		Address: common.HexToAddress("0x18CA0E045F0D772a851BC7e48357Bcaab0a0795D"),
   213  		Signers: []common.Address{
   214  			common.HexToAddress("0x4769bcaD07e3b938B7f43EB7D278Bc7Cb9efFb38"), // Peter
   215  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
   216  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
   217  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
   218  			common.HexToAddress("0x0DF8fa387C602AE62559cC4aFa4972A7045d6707"), // Guillaume
   219  		},
   220  		Threshold: 2,
   221  	}
   222  
   223  	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
   224  	// and accepted by the Ethereum core developers into the Ethash consensus.
   225  	//
   226  	// This configuration is intentionally not using keyed fields to force anyone
   227  	// adding flags to the config to also have to set these fields.
   228  	AllEthashProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil}
   229  
   230  	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
   231  	// and accepted by the Ethereum core developers into the Clique consensus.
   232  	//
   233  	// This configuration is intentionally not using keyed fields to force anyone
   234  	// adding flags to the config to also have to set these fields.
   235  	AllCliqueProtocolChanges = &ChainConfig{big.NewInt(1337), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}}
   236  
   237  	TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, new(EthashConfig), nil}
   238  	TestRules       = TestChainConfig.Rules(new(big.Int))
   239  )
   240  
   241  // TrustedCheckpoint represents a set of post-processed trie roots (CHT and
   242  // BloomTrie) associated with the appropriate section index and head hash. It is
   243  // used to start light syncing from this checkpoint and avoid downloading the
   244  // entire header chain while still being able to securely access old headers/logs.
   245  type TrustedCheckpoint struct {
   246  	SectionIndex uint64      `json:"sectionIndex"`
   247  	SectionHead  common.Hash `json:"sectionHead"`
   248  	CHTRoot      common.Hash `json:"chtRoot"`
   249  	BloomRoot    common.Hash `json:"bloomRoot"`
   250  }
   251  
   252  // HashEqual returns an indicator comparing the itself hash with given one.
   253  func (c *TrustedCheckpoint) HashEqual(hash common.Hash) bool {
   254  	if c.Empty() {
   255  		return hash == common.Hash{}
   256  	}
   257  	return c.Hash() == hash
   258  }
   259  
   260  // Hash returns the hash of checkpoint's four key fields(index, sectionHead, chtRoot and bloomTrieRoot).
   261  func (c *TrustedCheckpoint) Hash() common.Hash {
   262  	var sectionIndex [8]byte
   263  	binary.BigEndian.PutUint64(sectionIndex[:], c.SectionIndex)
   264  
   265  	w := sha3.NewLegacyKeccak256()
   266  	w.Write(sectionIndex[:])
   267  	w.Write(c.SectionHead[:])
   268  	w.Write(c.CHTRoot[:])
   269  	w.Write(c.BloomRoot[:])
   270  
   271  	var h common.Hash
   272  	w.Sum(h[:0])
   273  	return h
   274  }
   275  
   276  // Empty returns an indicator whether the checkpoint is regarded as empty.
   277  func (c *TrustedCheckpoint) Empty() bool {
   278  	return c.SectionHead == (common.Hash{}) || c.CHTRoot == (common.Hash{}) || c.BloomRoot == (common.Hash{})
   279  }
   280  
   281  // CheckpointOracleConfig represents a set of checkpoint contract(which acts as an oracle)
   282  // config which used for light client checkpoint syncing.
   283  type CheckpointOracleConfig struct {
   284  	Address   common.Address   `json:"address"`
   285  	Signers   []common.Address `json:"signers"`
   286  	Threshold uint64           `json:"threshold"`
   287  }
   288  
   289  // ChainConfig is the core config which determines the blockchain settings.
   290  //
   291  // ChainConfig is stored in the database on a per block basis. This means
   292  // that any network, identified by its genesis block, can have its own
   293  // set of configuration options.
   294  type ChainConfig struct {
   295  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   296  
   297  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   298  
   299  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   300  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   301  
   302  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   303  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   304  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   305  
   306  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   307  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   308  
   309  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   310  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   311  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
   312  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
   313  	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
   314  	BerlinBlock         *big.Int `json:"berlinBlock,omitempty"`         // Berlin switch block (nil = no fork, 0 = already on berlin)
   315  	LondonBlock         *big.Int `json:"londonBlock,omitempty"`         // London switch block (nil = no fork, 0 = already on london)
   316  
   317  	CatalystBlock *big.Int `json:"catalystBlock,omitempty"` // Catalyst switch block (nil = no fork, 0 = already on catalyst)
   318  
   319  	// Various consensus engines
   320  	Ethash *EthashConfig `json:"ethash,omitempty"`
   321  	Clique *CliqueConfig `json:"clique,omitempty"`
   322  }
   323  
   324  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   325  type EthashConfig struct{}
   326  
   327  // String implements the stringer interface, returning the consensus engine details.
   328  func (c *EthashConfig) String() string {
   329  	return "ethash"
   330  }
   331  
   332  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   333  type CliqueConfig struct {
   334  	Period uint64 `json:"period"` // Number of seconds between blocks to enforce
   335  	Epoch  uint64 `json:"epoch"`  // Epoch length to reset votes and checkpoint
   336  }
   337  
   338  // String implements the stringer interface, returning the consensus engine details.
   339  func (c *CliqueConfig) String() string {
   340  	return "clique"
   341  }
   342  
   343  // String implements the fmt.Stringer interface.
   344  func (c *ChainConfig) String() string {
   345  	var engine interface{}
   346  	switch {
   347  	case c.Ethash != nil:
   348  		engine = c.Ethash
   349  	case c.Clique != nil:
   350  		engine = c.Clique
   351  	default:
   352  		engine = "unknown"
   353  	}
   354  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v, Berlin: %v, London: %v, Engine: %v}",
   355  		c.ChainID,
   356  		c.HomesteadBlock,
   357  		c.DAOForkBlock,
   358  		c.DAOForkSupport,
   359  		c.EIP150Block,
   360  		c.EIP155Block,
   361  		c.EIP158Block,
   362  		c.ByzantiumBlock,
   363  		c.ConstantinopleBlock,
   364  		c.PetersburgBlock,
   365  		c.IstanbulBlock,
   366  		c.MuirGlacierBlock,
   367  		c.BerlinBlock,
   368  		c.LondonBlock,
   369  		engine,
   370  	)
   371  }
   372  
   373  // IsHomestead returns whether num is either equal to the homestead block or greater.
   374  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   375  	return isForked(c.HomesteadBlock, num)
   376  }
   377  
   378  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   379  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   380  	return isForked(c.DAOForkBlock, num)
   381  }
   382  
   383  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   384  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   385  	return isForked(c.EIP150Block, num)
   386  }
   387  
   388  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   389  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   390  	return isForked(c.EIP155Block, num)
   391  }
   392  
   393  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   394  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   395  	return isForked(c.EIP158Block, num)
   396  }
   397  
   398  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   399  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   400  	return isForked(c.ByzantiumBlock, num)
   401  }
   402  
   403  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   404  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   405  	return isForked(c.ConstantinopleBlock, num)
   406  }
   407  
   408  // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
   409  func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
   410  	return isForked(c.MuirGlacierBlock, num)
   411  }
   412  
   413  // IsPetersburg returns whether num is either
   414  // - equal to or greater than the PetersburgBlock fork block,
   415  // - OR is nil, and Constantinople is active
   416  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   417  	return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num)
   418  }
   419  
   420  // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater.
   421  func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
   422  	return isForked(c.IstanbulBlock, num)
   423  }
   424  
   425  // IsBerlin returns whether num is either equal to the Berlin fork block or greater.
   426  func (c *ChainConfig) IsBerlin(num *big.Int) bool {
   427  	return isForked(c.BerlinBlock, num)
   428  }
   429  
   430  // IsLondon returns whether num is either equal to the London fork block or greater.
   431  func (c *ChainConfig) IsLondon(num *big.Int) bool {
   432  	return isForked(c.LondonBlock, num)
   433  }
   434  
   435  // IsCatalyst returns whether num is either equal to the Merge fork block or greater.
   436  func (c *ChainConfig) IsCatalyst(num *big.Int) bool {
   437  	return isForked(c.CatalystBlock, num)
   438  }
   439  
   440  // CheckCompatible checks whether scheduled fork transitions have been imported
   441  // with a mismatching chain configuration.
   442  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError {
   443  	bhead := new(big.Int).SetUint64(height)
   444  
   445  	// Iterate checkCompatible to find the lowest conflict.
   446  	var lasterr *ConfigCompatError
   447  	for {
   448  		err := c.checkCompatible(newcfg, bhead)
   449  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   450  			break
   451  		}
   452  		lasterr = err
   453  		bhead.SetUint64(err.RewindTo)
   454  	}
   455  	return lasterr
   456  }
   457  
   458  // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
   459  // to guarantee that forks can be implemented in a different order than on official networks
   460  func (c *ChainConfig) CheckConfigForkOrder() error {
   461  	type fork struct {
   462  		name     string
   463  		block    *big.Int
   464  		optional bool // if true, the fork may be nil and next fork is still allowed
   465  	}
   466  	var lastFork fork
   467  	for _, cur := range []fork{
   468  		{name: "homesteadBlock", block: c.HomesteadBlock},
   469  		{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
   470  		{name: "eip150Block", block: c.EIP150Block},
   471  		{name: "eip155Block", block: c.EIP155Block},
   472  		{name: "eip158Block", block: c.EIP158Block},
   473  		{name: "byzantiumBlock", block: c.ByzantiumBlock},
   474  		{name: "constantinopleBlock", block: c.ConstantinopleBlock},
   475  		{name: "petersburgBlock", block: c.PetersburgBlock},
   476  		{name: "istanbulBlock", block: c.IstanbulBlock},
   477  		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
   478  		{name: "berlinBlock", block: c.BerlinBlock},
   479  		{name: "londonBlock", block: c.LondonBlock},
   480  	} {
   481  		if lastFork.name != "" {
   482  			// Next one must be higher number
   483  			if lastFork.block == nil && cur.block != nil {
   484  				return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
   485  					lastFork.name, cur.name, cur.block)
   486  			}
   487  			if lastFork.block != nil && cur.block != nil {
   488  				if lastFork.block.Cmp(cur.block) > 0 {
   489  					return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
   490  						lastFork.name, lastFork.block, cur.name, cur.block)
   491  				}
   492  			}
   493  		}
   494  		// If it was optional and not set, then ignore it
   495  		if !cur.optional || cur.block != nil {
   496  			lastFork = cur
   497  		}
   498  	}
   499  	return nil
   500  }
   501  
   502  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError {
   503  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   504  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   505  	}
   506  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   507  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   508  	}
   509  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   510  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   511  	}
   512  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   513  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   514  	}
   515  	if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   516  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   517  	}
   518  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   519  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   520  	}
   521  	if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   522  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   523  	}
   524  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   525  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   526  	}
   527  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   528  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   529  	}
   530  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) {
   531  		// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
   532  		// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
   533  		if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) {
   534  			return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   535  		}
   536  	}
   537  	if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) {
   538  		return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   539  	}
   540  	if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) {
   541  		return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
   542  	}
   543  	if isForkIncompatible(c.BerlinBlock, newcfg.BerlinBlock, head) {
   544  		return newCompatError("Berlin fork block", c.BerlinBlock, newcfg.BerlinBlock)
   545  	}
   546  	if isForkIncompatible(c.LondonBlock, newcfg.LondonBlock, head) {
   547  		return newCompatError("London fork block", c.LondonBlock, newcfg.LondonBlock)
   548  	}
   549  	return nil
   550  }
   551  
   552  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   553  // block s2 because head is already past the fork.
   554  func isForkIncompatible(s1, s2, head *big.Int) bool {
   555  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   556  }
   557  
   558  // isForked returns whether a fork scheduled at block s is active at the given head block.
   559  func isForked(s, head *big.Int) bool {
   560  	if s == nil || head == nil {
   561  		return false
   562  	}
   563  	return s.Cmp(head) <= 0
   564  }
   565  
   566  func configNumEqual(x, y *big.Int) bool {
   567  	if x == nil {
   568  		return y == nil
   569  	}
   570  	if y == nil {
   571  		return x == nil
   572  	}
   573  	return x.Cmp(y) == 0
   574  }
   575  
   576  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   577  // ChainConfig that would alter the past.
   578  type ConfigCompatError struct {
   579  	What string
   580  	// block numbers of the stored and new configurations
   581  	StoredConfig, NewConfig *big.Int
   582  	// the block number to which the local chain must be rewound to correct the error
   583  	RewindTo uint64
   584  }
   585  
   586  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   587  	var rew *big.Int
   588  	switch {
   589  	case storedblock == nil:
   590  		rew = newblock
   591  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   592  		rew = storedblock
   593  	default:
   594  		rew = newblock
   595  	}
   596  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   597  	if rew != nil && rew.Sign() > 0 {
   598  		err.RewindTo = rew.Uint64() - 1
   599  	}
   600  	return err
   601  }
   602  
   603  func (err *ConfigCompatError) Error() string {
   604  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   605  }
   606  
   607  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   608  // that do not have or require information about the block.
   609  //
   610  // Rules is a one time interface meaning that it shouldn't be used in between transition
   611  // phases.
   612  type Rules struct {
   613  	ChainID                                                 *big.Int
   614  	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
   615  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
   616  	IsBerlin, IsLondon, IsCatalyst                          bool
   617  }
   618  
   619  // Rules ensures c's ChainID is not nil.
   620  func (c *ChainConfig) Rules(num *big.Int) Rules {
   621  	chainID := c.ChainID
   622  	if chainID == nil {
   623  		chainID = new(big.Int)
   624  	}
   625  	return Rules{
   626  		ChainID:          new(big.Int).Set(chainID),
   627  		IsHomestead:      c.IsHomestead(num),
   628  		IsEIP150:         c.IsEIP150(num),
   629  		IsEIP155:         c.IsEIP155(num),
   630  		IsEIP158:         c.IsEIP158(num),
   631  		IsByzantium:      c.IsByzantium(num),
   632  		IsConstantinople: c.IsConstantinople(num),
   633  		IsPetersburg:     c.IsPetersburg(num),
   634  		IsIstanbul:       c.IsIstanbul(num),
   635  		IsBerlin:         c.IsBerlin(num),
   636  		IsLondon:         c.IsLondon(num),
   637  		IsCatalyst:       c.IsCatalyst(num),
   638  	}
   639  }