github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/params/config.go (about)

     1  // Copyright 2016 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 params
    18  
    19  import (
    20  	"encoding/binary"
    21  	"errors"
    22  	"fmt"
    23  	"math/big"
    24  
    25  	"github.com/kisexp/xdchain/common"
    26  	"github.com/kisexp/xdchain/crypto"
    27  )
    28  
    29  // Genesis hashes to enforce below configs on.
    30  var (
    31  	MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3")
    32  	RopstenGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d")
    33  	RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177")
    34  	GoerliGenesisHash  = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a")
    35  	// TODO: update with yolov2 values
    36  	YoloV2GenesisHash = common.HexToHash("0x498a7239036dd2cd09e2bb8a80922b78632017958c332b42044c250d603a8a3e")
    37  )
    38  
    39  // TrustedCheckpoints associates each known checkpoint with the genesis hash of
    40  // the chain it belongs to.
    41  var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{
    42  	MainnetGenesisHash: MainnetTrustedCheckpoint,
    43  	RopstenGenesisHash: RopstenTrustedCheckpoint,
    44  	RinkebyGenesisHash: RinkebyTrustedCheckpoint,
    45  	GoerliGenesisHash:  GoerliTrustedCheckpoint,
    46  }
    47  
    48  // CheckpointOracles associates each known checkpoint oracles with the genesis hash of
    49  // the chain it belongs to.
    50  var CheckpointOracles = map[common.Hash]*CheckpointOracleConfig{
    51  	MainnetGenesisHash: MainnetCheckpointOracle,
    52  	RopstenGenesisHash: RopstenCheckpointOracle,
    53  	RinkebyGenesisHash: RinkebyCheckpointOracle,
    54  	GoerliGenesisHash:  GoerliCheckpointOracle,
    55  }
    56  
    57  var (
    58  	// MainnetChainConfig is the chain parameters to run a node on the main network.
    59  	MainnetChainConfig = &ChainConfig{
    60  		ChainID:             big.NewInt(1),
    61  		HomesteadBlock:      big.NewInt(1150000),
    62  		DAOForkBlock:        big.NewInt(1920000),
    63  		DAOForkSupport:      true,
    64  		EIP150Block:         big.NewInt(2463000),
    65  		EIP150Hash:          common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"),
    66  		EIP155Block:         big.NewInt(2675000),
    67  		EIP158Block:         big.NewInt(2675000),
    68  		ByzantiumBlock:      big.NewInt(4370000),
    69  		ConstantinopleBlock: big.NewInt(7280000),
    70  		PetersburgBlock:     big.NewInt(7280000),
    71  		IstanbulBlock:       big.NewInt(9069000),
    72  		MuirGlacierBlock:    big.NewInt(9200000),
    73  		Ethash:              new(EthashConfig),
    74  	}
    75  
    76  	// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
    77  	MainnetTrustedCheckpoint = &TrustedCheckpoint{
    78  		SectionIndex: 345,
    79  		SectionHead:  common.HexToHash("0x5453bab878704adebc934b41fd214a07ea7a72b8572ff088dca7f7956cd0ef28"),
    80  		CHTRoot:      common.HexToHash("0x7693d432595846c094f47cb37f5c868b0b7b1968fc6b0fc411ded1345fdaffab"),
    81  		BloomRoot:    common.HexToHash("0x8b0e7895bc39840d8dac857e26bdf3d0a07684b0b962b252546659e0337a9f70"),
    82  	}
    83  
    84  	// MainnetCheckpointOracle contains a set of configs for the main network oracle.
    85  	MainnetCheckpointOracle = &CheckpointOracleConfig{
    86  		Address: common.HexToAddress("0x9a9070028361F7AAbeB3f2F2Dc07F82C4a98A02a"),
    87  		Signers: []common.Address{
    88  			common.HexToAddress("0x1b2C260efc720BE89101890E4Db589b44E950527"), // Peter
    89  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
    90  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
    91  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
    92  			common.HexToAddress("0x0DF8fa387C602AE62559cC4aFa4972A7045d6707"), // Guillaume
    93  		},
    94  		Threshold: 2,
    95  	}
    96  
    97  	// RopstenChainConfig contains the chain parameters to run a node on the Ropsten test network.
    98  	RopstenChainConfig = &ChainConfig{
    99  		ChainID:             big.NewInt(3),
   100  		HomesteadBlock:      big.NewInt(0),
   101  		DAOForkBlock:        nil,
   102  		DAOForkSupport:      true,
   103  		EIP150Block:         big.NewInt(0),
   104  		EIP150Hash:          common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"),
   105  		EIP155Block:         big.NewInt(10),
   106  		EIP158Block:         big.NewInt(10),
   107  		ByzantiumBlock:      big.NewInt(1700000),
   108  		ConstantinopleBlock: big.NewInt(4230000),
   109  		PetersburgBlock:     big.NewInt(4939394),
   110  		IstanbulBlock:       big.NewInt(6485846),
   111  		MuirGlacierBlock:    big.NewInt(7117117),
   112  		Ethash:              new(EthashConfig),
   113  	}
   114  
   115  	// RopstenTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
   116  	RopstenTrustedCheckpoint = &TrustedCheckpoint{
   117  		SectionIndex: 279,
   118  		SectionHead:  common.HexToHash("0x4a4912848d4c06090097073357c10015d11c6f4544a0f93cbdd584701c3b7d58"),
   119  		CHTRoot:      common.HexToHash("0x9053b7867ae921e80a4e2f5a4b15212e4af3d691ca712fb33dc150e9c6ea221c"),
   120  		BloomRoot:    common.HexToHash("0x3dc04cb1be7ddc271f3f83469b47b76184a79d7209ef51d85b1539ea6d25a645"),
   121  	}
   122  
   123  	// RopstenCheckpointOracle contains a set of configs for the Ropsten test network oracle.
   124  	RopstenCheckpointOracle = &CheckpointOracleConfig{
   125  		Address: common.HexToAddress("0xEF79475013f154E6A65b54cB2742867791bf0B84"),
   126  		Signers: []common.Address{
   127  			common.HexToAddress("0x32162F3581E88a5f62e8A61892B42C46E2c18f7b"), // Peter
   128  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
   129  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
   130  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
   131  			common.HexToAddress("0x0DF8fa387C602AE62559cC4aFa4972A7045d6707"), // Guillaume
   132  		},
   133  		Threshold: 2,
   134  	}
   135  
   136  	// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
   137  	RinkebyChainConfig = &ChainConfig{
   138  		ChainID:             big.NewInt(4),
   139  		HomesteadBlock:      big.NewInt(1),
   140  		DAOForkBlock:        nil,
   141  		DAOForkSupport:      true,
   142  		EIP150Block:         big.NewInt(2),
   143  		EIP150Hash:          common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"),
   144  		EIP155Block:         big.NewInt(3),
   145  		EIP158Block:         big.NewInt(3),
   146  		ByzantiumBlock:      big.NewInt(1035301),
   147  		ConstantinopleBlock: big.NewInt(3660663),
   148  		PetersburgBlock:     big.NewInt(4321234),
   149  		IstanbulBlock:       big.NewInt(5435345),
   150  		MuirGlacierBlock:    nil,
   151  		Clique: &CliqueConfig{
   152  			Period: 15,
   153  			Epoch:  30000,
   154  		},
   155  	}
   156  
   157  	// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
   158  	RinkebyTrustedCheckpoint = &TrustedCheckpoint{
   159  		SectionIndex: 232,
   160  		SectionHead:  common.HexToHash("0x8170fca4039b11a008c11f9996ff112151cbb17411437bb2f86288e11158b2f0"),
   161  		CHTRoot:      common.HexToHash("0x4526560d92ae1b3a6d3ee780c3ad289ba2bbf1b5da58d9ea107f2f26412b631f"),
   162  		BloomRoot:    common.HexToHash("0x82a889098a35d6a21ea8894d35a1db69b94bad61b988bbe5ae4601437320e331"),
   163  	}
   164  
   165  	// RinkebyCheckpointOracle contains a set of configs for the Rinkeby test network oracle.
   166  	RinkebyCheckpointOracle = &CheckpointOracleConfig{
   167  		Address: common.HexToAddress("0xebe8eFA441B9302A0d7eaECc277c09d20D684540"),
   168  		Signers: []common.Address{
   169  			common.HexToAddress("0xd9c9cd5f6779558b6e0ed4e6acf6b1947e7fa1f3"), // Peter
   170  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
   171  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
   172  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
   173  		},
   174  		Threshold: 2,
   175  	}
   176  
   177  	// GoerliChainConfig contains the chain parameters to run a node on the Görli test network.
   178  	GoerliChainConfig = &ChainConfig{
   179  		ChainID:             big.NewInt(5),
   180  		HomesteadBlock:      big.NewInt(0),
   181  		DAOForkBlock:        nil,
   182  		DAOForkSupport:      true,
   183  		EIP150Block:         big.NewInt(0),
   184  		EIP155Block:         big.NewInt(0),
   185  		EIP158Block:         big.NewInt(0),
   186  		ByzantiumBlock:      big.NewInt(0),
   187  		ConstantinopleBlock: big.NewInt(0),
   188  		PetersburgBlock:     big.NewInt(0),
   189  		IstanbulBlock:       big.NewInt(1561651),
   190  		MuirGlacierBlock:    nil,
   191  		Clique: &CliqueConfig{
   192  			Period: 15,
   193  			Epoch:  30000,
   194  		},
   195  	}
   196  
   197  	// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
   198  	GoerliTrustedCheckpoint = &TrustedCheckpoint{
   199  		SectionIndex: 116,
   200  		SectionHead:  common.HexToHash("0xf2d200f636f213c9c7bb4e747ff564813da7708253037103aef3d8be5203c5e1"),
   201  		CHTRoot:      common.HexToHash("0xb0ac83e2ccf6c2776945e099c4e3df50fe6200499c8b2045c34cafdf57d15087"),
   202  		BloomRoot:    common.HexToHash("0xfb580ad1c611230a4bfc56534f58bcb156d028bc6ce70e35403dc019c7c02d90"),
   203  	}
   204  
   205  	// GoerliCheckpointOracle contains a set of configs for the Goerli test network oracle.
   206  	GoerliCheckpointOracle = &CheckpointOracleConfig{
   207  		Address: common.HexToAddress("0x18CA0E045F0D772a851BC7e48357Bcaab0a0795D"),
   208  		Signers: []common.Address{
   209  			common.HexToAddress("0x4769bcaD07e3b938B7f43EB7D278Bc7Cb9efFb38"), // Peter
   210  			common.HexToAddress("0x78d1aD571A1A09D60D9BBf25894b44e4C8859595"), // Martin
   211  			common.HexToAddress("0x286834935f4A8Cfb4FF4C77D5770C2775aE2b0E7"), // Zsolt
   212  			common.HexToAddress("0xb86e2B0Ab5A4B1373e40c51A7C712c70Ba2f9f8E"), // Gary
   213  			common.HexToAddress("0x0DF8fa387C602AE62559cC4aFa4972A7045d6707"), // Guillaume
   214  		},
   215  		Threshold: 2,
   216  	}
   217  
   218  	// YoloV2ChainConfig contains the chain parameters to run a node on the YOLOv2 test network.
   219  	YoloV2ChainConfig = &ChainConfig{
   220  		ChainID:             big.NewInt(133519467574834),
   221  		HomesteadBlock:      big.NewInt(0),
   222  		DAOForkBlock:        nil,
   223  		DAOForkSupport:      true,
   224  		EIP150Block:         big.NewInt(0),
   225  		EIP155Block:         big.NewInt(0),
   226  		EIP158Block:         big.NewInt(0),
   227  		ByzantiumBlock:      big.NewInt(0),
   228  		ConstantinopleBlock: big.NewInt(0),
   229  		PetersburgBlock:     big.NewInt(0),
   230  		IstanbulBlock:       big.NewInt(0),
   231  		MuirGlacierBlock:    nil,
   232  		YoloV2Block:         big.NewInt(0),
   233  		Clique: &CliqueConfig{
   234  			Period: 15,
   235  			Epoch:  30000,
   236  		},
   237  	}
   238  
   239  	// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
   240  	// and accepted by the Ethereum core developers into the Ethash consensus.
   241  	//
   242  	// This configuration is intentionally not using keyed fields to force anyone
   243  	// adding flags to the config to also have to set these fields.
   244  	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), nil, nil, nil, new(EthashConfig), nil, nil, false, 32, 35, big.NewInt(0), big.NewInt(0), nil, nil, false, nil}
   245  
   246  	// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
   247  	// and accepted by the Ethereum core developers into the Clique consensus.
   248  	//
   249  	// This configuration is intentionally not using keyed fields to force anyone
   250  	// adding flags to the config to also have to set these fields.
   251  	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), nil, nil, nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil, nil, false, nil}
   252  
   253  	TestChainConfig = &ChainConfig{big.NewInt(10), 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), nil, nil, nil, new(EthashConfig), nil, nil, false, 32, 32, big.NewInt(0), big.NewInt(0), nil, nil, false, nil}
   254  	TestRules       = TestChainConfig.Rules(new(big.Int))
   255  
   256  	QuorumTestChainConfig    = &ChainConfig{big.NewInt(10), 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), nil, nil, nil, new(EthashConfig), nil, nil, true, 64, 32, big.NewInt(0), big.NewInt(0), nil, big.NewInt(0), false, nil}
   257  	QuorumMPSTestChainConfig = &ChainConfig{big.NewInt(10), 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), nil, nil, nil, new(EthashConfig), nil, nil, true, 64, 32, big.NewInt(0), big.NewInt(0), nil, big.NewInt(0), true, nil}
   258  )
   259  
   260  // TrustedCheckpoint represents a set of post-processed trie roots (CHT and
   261  // BloomTrie) associated with the appropriate section index and head hash. It is
   262  // used to start light syncing from this checkpoint and avoid downloading the
   263  // entire header chain while still being able to securely access old headers/logs.
   264  type TrustedCheckpoint struct {
   265  	SectionIndex uint64      `json:"sectionIndex"`
   266  	SectionHead  common.Hash `json:"sectionHead"`
   267  	CHTRoot      common.Hash `json:"chtRoot"`
   268  	BloomRoot    common.Hash `json:"bloomRoot"`
   269  }
   270  
   271  // HashEqual returns an indicator comparing the itself hash with given one.
   272  func (c *TrustedCheckpoint) HashEqual(hash common.Hash) bool {
   273  	if c.Empty() {
   274  		return hash == common.Hash{}
   275  	}
   276  	return c.Hash() == hash
   277  }
   278  
   279  // Hash returns the hash of checkpoint's four key fields(index, sectionHead, chtRoot and bloomTrieRoot).
   280  func (c *TrustedCheckpoint) Hash() common.Hash {
   281  	buf := make([]byte, 8+3*common.HashLength)
   282  	binary.BigEndian.PutUint64(buf, c.SectionIndex)
   283  	copy(buf[8:], c.SectionHead.Bytes())
   284  	copy(buf[8+common.HashLength:], c.CHTRoot.Bytes())
   285  	copy(buf[8+2*common.HashLength:], c.BloomRoot.Bytes())
   286  	return crypto.Keccak256Hash(buf)
   287  }
   288  
   289  // Empty returns an indicator whether the checkpoint is regarded as empty.
   290  func (c *TrustedCheckpoint) Empty() bool {
   291  	return c.SectionHead == (common.Hash{}) || c.CHTRoot == (common.Hash{}) || c.BloomRoot == (common.Hash{})
   292  }
   293  
   294  // CheckpointOracleConfig represents a set of checkpoint contract(which acts as an oracle)
   295  // config which used for light client checkpoint syncing.
   296  type CheckpointOracleConfig struct {
   297  	Address   common.Address   `json:"address"`
   298  	Signers   []common.Address `json:"signers"`
   299  	Threshold uint64           `json:"threshold"`
   300  }
   301  
   302  type MaxCodeConfigStruct struct {
   303  	Block *big.Int `json:"block,omitempty"`
   304  	Size  uint64   `json:"size,omitempty"`
   305  }
   306  
   307  // ChainConfig is the core config which determines the blockchain settings.
   308  //
   309  // ChainConfig is stored in the database on a per block basis. This means
   310  // that any network, identified by its genesis block, can have its own
   311  // set of configuration options.
   312  type ChainConfig struct {
   313  	ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
   314  
   315  	HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
   316  
   317  	DAOForkBlock   *big.Int `json:"daoForkBlock,omitempty"`   // TheDAO hard-fork switch block (nil = no fork)
   318  	DAOForkSupport bool     `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
   319  
   320  	// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
   321  	EIP150Block *big.Int    `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
   322  	EIP150Hash  common.Hash `json:"eip150Hash,omitempty"`  // EIP150 HF hash (needed for header only clients as only gas pricing changed)
   323  
   324  	EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
   325  	EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
   326  
   327  	ByzantiumBlock      *big.Int `json:"byzantiumBlock,omitempty"`      // Byzantium switch block (nil = no fork, 0 = already on byzantium)
   328  	ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
   329  	PetersburgBlock     *big.Int `json:"petersburgBlock,omitempty"`     // Petersburg switch block (nil = same as Constantinople)
   330  	IstanbulBlock       *big.Int `json:"istanbulBlock,omitempty"`       // Istanbul switch block (nil = no fork, 0 = already on istanbul)
   331  	MuirGlacierBlock    *big.Int `json:"muirGlacierBlock,omitempty"`    // Eip-2384 (bomb delay) switch block (nil = no fork, 0 = already activated)
   332  
   333  	YoloV2Block *big.Int `json:"yoloV2Block,omitempty"` // YOLO v2: Gas repricings TODO @holiman add EIP references
   334  	EWASMBlock  *big.Int `json:"ewasmBlock,omitempty"`  // EWASM switch block (nil = no fork, 0 = already activated)
   335  
   336  	// Various consensus engines
   337  	Ethash   *EthashConfig   `json:"ethash,omitempty"`
   338  	Clique   *CliqueConfig   `json:"clique,omitempty"`
   339  	Istanbul *IstanbulConfig `json:"istanbul,omitempty"` // Quorum
   340  
   341  	// Start of Quorum specific configs
   342  
   343  	IsQuorum             bool   `json:"isQuorum"`     // Quorum flag
   344  	TransactionSizeLimit uint64 `json:"txnSizeLimit"` // Quorum - transaction size limit
   345  	MaxCodeSize          uint64 `json:"maxCodeSize"`  // Quorum -  maximum CodeSize of contract
   346  
   347  	// QIP714Block implements the permissions related changes
   348  	QIP714Block            *big.Int `json:"qip714Block,omitempty"`
   349  	MaxCodeSizeChangeBlock *big.Int `json:"maxCodeSizeChangeBlock,omitempty"`
   350  	// to track multiple changes to maxCodeSize
   351  	MaxCodeSizeConfig        []MaxCodeConfigStruct `json:"maxCodeSizeConfig,omitempty"`
   352  	PrivacyEnhancementsBlock *big.Int              `json:"privacyEnhancementsBlock,omitempty"`
   353  	IsMPS                    bool                  `json:"isMPS"`                            // multiple private states flag
   354  	PrivacyPrecompileBlock   *big.Int              `json:"privacyPrecompileBlock,omitempty"` // Switch block to enable privacy precompiled contract to process privacy marker transactions
   355  
   356  	// End of Quorum specific configs
   357  }
   358  
   359  // EthashConfig is the consensus engine configs for proof-of-work based sealing.
   360  type EthashConfig struct{}
   361  
   362  // String implements the stringer interface, returning the consensus engine details.
   363  func (c *EthashConfig) String() string {
   364  	return "ethash"
   365  }
   366  
   367  // CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
   368  type CliqueConfig struct {
   369  	Period                 uint64 `json:"period"`                 // Number of seconds between blocks to enforce
   370  	Epoch                  uint64 `json:"epoch"`                  // Epoch length to reset votes and checkpoint
   371  	AllowedFutureBlockTime uint64 `json:"allowedFutureBlockTime"` // Max time (in seconds) from current time allowed for blocks, before they're considered future blocks
   372  }
   373  
   374  // String implements the stringer interface, returning the consensus engine details.
   375  func (c *CliqueConfig) String() string {
   376  	return "clique"
   377  }
   378  
   379  // IstanbulConfig is the consensus engine configs for Istanbul based sealing.
   380  type IstanbulConfig struct {
   381  	Epoch          uint64   `json:"epoch"`                    // Epoch length to reset votes and checkpoint
   382  	ProposerPolicy uint64   `json:"policy"`                   // The policy for proposer selection
   383  	Ceil2Nby3Block *big.Int `json:"ceil2Nby3Block,omitempty"` // Number of confirmations required to move from one state to next [2F + 1 to Ceil(2N/3)]
   384  	TestQBFTBlock  *big.Int `json:"testQBFTBlock,omitempty"`  // Fork block at which block confirmations are done using qbft consensus instead of ibft
   385  }
   386  
   387  // String implements the stringer interface, returning the consensus engine details.
   388  func (c *IstanbulConfig) String() string {
   389  	return "istanbul"
   390  }
   391  
   392  // String implements the fmt.Stringer interface.
   393  func (c *ChainConfig) String() string {
   394  	var engine interface{}
   395  	switch {
   396  	case c.Ethash != nil:
   397  		engine = c.Ethash
   398  	case c.Clique != nil:
   399  		engine = c.Clique
   400  	case c.Istanbul != nil:
   401  		engine = c.Istanbul
   402  	default:
   403  		engine = "unknown"
   404  	}
   405  	return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v IsQuorum: %v Constantinople: %v TransactionSizeLimit: %v MaxCodeSize: %v Petersburg: %v Istanbul: %v, Muir Glacier: %v YOLO v2: %v PrivacyEnhancements: %v PrivacyPrecompile: %v Engine: %v}",
   406  		c.ChainID,
   407  		c.HomesteadBlock,
   408  		c.DAOForkBlock,
   409  		c.DAOForkSupport,
   410  		c.EIP150Block,
   411  		c.EIP155Block,
   412  		c.EIP158Block,
   413  		c.ByzantiumBlock,
   414  		c.IsQuorum,
   415  		c.ConstantinopleBlock,
   416  		c.TransactionSizeLimit,
   417  		c.MaxCodeSize,
   418  		c.PetersburgBlock,
   419  		c.IstanbulBlock,
   420  		c.MuirGlacierBlock,
   421  		c.YoloV2Block,
   422  		c.PrivacyEnhancementsBlock,
   423  		c.PrivacyPrecompileBlock,
   424  		engine,
   425  	)
   426  }
   427  
   428  // Quorum - validate code size and transaction size limit
   429  func (c *ChainConfig) IsValid() error {
   430  
   431  	if c.TransactionSizeLimit < 32 || c.TransactionSizeLimit > 128 {
   432  		return errors.New("Genesis transaction size limit must be between 32 and 128")
   433  	}
   434  
   435  	if c.MaxCodeSize != 0 && (c.MaxCodeSize < 24 || c.MaxCodeSize > 128) {
   436  		return errors.New("Genesis max code size must be between 24 and 128")
   437  	}
   438  
   439  	return nil
   440  }
   441  
   442  // IsHomestead returns whether num is either equal to the homestead block or greater.
   443  func (c *ChainConfig) IsHomestead(num *big.Int) bool {
   444  	return isForked(c.HomesteadBlock, num)
   445  }
   446  
   447  // IsDAOFork returns whether num is either equal to the DAO fork block or greater.
   448  func (c *ChainConfig) IsDAOFork(num *big.Int) bool {
   449  	return isForked(c.DAOForkBlock, num)
   450  }
   451  
   452  // IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
   453  func (c *ChainConfig) IsEIP150(num *big.Int) bool {
   454  	return isForked(c.EIP150Block, num)
   455  }
   456  
   457  // IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
   458  func (c *ChainConfig) IsEIP155(num *big.Int) bool {
   459  	return isForked(c.EIP155Block, num)
   460  }
   461  
   462  // IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
   463  func (c *ChainConfig) IsEIP158(num *big.Int) bool {
   464  	return isForked(c.EIP158Block, num)
   465  }
   466  
   467  // IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
   468  func (c *ChainConfig) IsByzantium(num *big.Int) bool {
   469  	return isForked(c.ByzantiumBlock, num)
   470  }
   471  
   472  // IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
   473  func (c *ChainConfig) IsConstantinople(num *big.Int) bool {
   474  	return isForked(c.ConstantinopleBlock, num)
   475  }
   476  
   477  // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater.
   478  func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool {
   479  	return isForked(c.MuirGlacierBlock, num)
   480  }
   481  
   482  // IsPetersburg returns whether num is either
   483  // - equal to or greater than the PetersburgBlock fork block,
   484  // - OR is nil, and Constantinople is active
   485  func (c *ChainConfig) IsPetersburg(num *big.Int) bool {
   486  	return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num)
   487  }
   488  
   489  // IsIstanbul returns whether num is either equal to the Istanbul fork block or greater.
   490  func (c *ChainConfig) IsIstanbul(num *big.Int) bool {
   491  	return isForked(c.IstanbulBlock, num)
   492  }
   493  
   494  // IsYoloV2 returns whether num is either equal to the YoloV2 fork block or greater.
   495  func (c *ChainConfig) IsYoloV2(num *big.Int) bool {
   496  	return isForked(c.YoloV2Block, num)
   497  }
   498  
   499  // IsEWASM returns whether num represents a block number after the EWASM fork
   500  func (c *ChainConfig) IsEWASM(num *big.Int) bool {
   501  	return isForked(c.EWASMBlock, num)
   502  }
   503  
   504  // Quorum
   505  //
   506  // IsQIP714 returns whether num represents a block number where permissions is enabled
   507  func (c *ChainConfig) IsQIP714(num *big.Int) bool {
   508  	return isForked(c.QIP714Block, num)
   509  }
   510  
   511  // IsMaxCodeSizeChangeBlock returns whether num represents a block number
   512  // where maxCodeSize change was done
   513  func (c *ChainConfig) IsMaxCodeSizeChangeBlock(num *big.Int) bool {
   514  	return isForked(c.MaxCodeSizeChangeBlock, num)
   515  }
   516  
   517  // Quorum
   518  //
   519  // GetMaxCodeSize returns maxCodeSize for the given block number
   520  func (c *ChainConfig) GetMaxCodeSize(num *big.Int) int {
   521  	maxCodeSize := MaxCodeSize
   522  
   523  	if len(c.MaxCodeSizeConfig) > 0 {
   524  		for _, data := range c.MaxCodeSizeConfig {
   525  			if data.Block.Cmp(num) > 0 {
   526  				break
   527  			}
   528  			maxCodeSize = int(data.Size) * 1024
   529  		}
   530  	} else if c.MaxCodeSize > 0 {
   531  		if c.MaxCodeSizeChangeBlock != nil && c.MaxCodeSizeChangeBlock.Cmp(big.NewInt(0)) >= 0 {
   532  			if c.IsMaxCodeSizeChangeBlock(num) {
   533  				maxCodeSize = int(c.MaxCodeSize) * 1024
   534  			}
   535  		} else {
   536  			maxCodeSize = int(c.MaxCodeSize) * 1024
   537  		}
   538  	}
   539  	return maxCodeSize
   540  }
   541  
   542  // Quorum
   543  //
   544  // validates the maxCodeSizeConfig data passed in config
   545  func (c *ChainConfig) CheckMaxCodeConfigData() error {
   546  	if c.MaxCodeSize != 0 || (c.MaxCodeSizeChangeBlock != nil && c.MaxCodeSizeChangeBlock.Cmp(big.NewInt(0)) >= 0) {
   547  		return errors.New("maxCodeSize & maxCodeSizeChangeBlock deprecated. Consider using maxCodeSizeConfig")
   548  	}
   549  	// validate max code size data
   550  	// 1. Code size should not be less than 24 and greater than 128
   551  	// 2. block entries are in ascending order
   552  	prevBlock := big.NewInt(0)
   553  	for _, data := range c.MaxCodeSizeConfig {
   554  		if data.Size < 24 || data.Size > 128 {
   555  			return errors.New("Genesis max code size must be between 24 and 128")
   556  		}
   557  		if data.Block == nil {
   558  			return errors.New("Block number not given in maxCodeSizeConfig data")
   559  		}
   560  		if data.Block.Cmp(prevBlock) < 0 {
   561  			return errors.New("invalid maxCodeSize detail, block order has to be ascending")
   562  		}
   563  		prevBlock = data.Block
   564  	}
   565  
   566  	return nil
   567  }
   568  
   569  // Quorum
   570  //
   571  // checks if changes to maxCodeSizeConfig proposed are compatible
   572  // with already existing genesis data
   573  func isMaxCodeSizeConfigCompatible(c1, c2 *ChainConfig, head *big.Int) (error, *big.Int, *big.Int) {
   574  	if len(c1.MaxCodeSizeConfig) == 0 && len(c2.MaxCodeSizeConfig) == 0 {
   575  		// maxCodeSizeConfig not used. return
   576  		return nil, big.NewInt(0), big.NewInt(0)
   577  	}
   578  
   579  	// existing config had maxCodeSizeConfig and new one does not have the same return error
   580  	if len(c1.MaxCodeSizeConfig) > 0 && len(c2.MaxCodeSizeConfig) == 0 {
   581  		return fmt.Errorf("genesis file missing max code size information"), head, head
   582  	}
   583  
   584  	if len(c2.MaxCodeSizeConfig) > 0 && len(c1.MaxCodeSizeConfig) == 0 {
   585  		return nil, big.NewInt(0), big.NewInt(0)
   586  	}
   587  
   588  	// check the number of records below current head in both configs
   589  	// if they do not match throw an error
   590  	c1RecsBelowHead := 0
   591  	for _, data := range c1.MaxCodeSizeConfig {
   592  		if data.Block.Cmp(head) <= 0 {
   593  			c1RecsBelowHead++
   594  		} else {
   595  			break
   596  		}
   597  	}
   598  
   599  	c2RecsBelowHead := 0
   600  	for _, data := range c2.MaxCodeSizeConfig {
   601  		if data.Block.Cmp(head) <= 0 {
   602  			c2RecsBelowHead++
   603  		} else {
   604  			break
   605  		}
   606  	}
   607  
   608  	// if the count of past records is not matching return error
   609  	if c1RecsBelowHead != c2RecsBelowHead {
   610  		return errors.New("maxCodeSizeConfig data incompatible. updating maxCodeSize for past"), head, head
   611  	}
   612  
   613  	// validate that each past record is matching exactly. if not return error
   614  	for i := 0; i < c1RecsBelowHead; i++ {
   615  		if c1.MaxCodeSizeConfig[i].Block.Cmp(c2.MaxCodeSizeConfig[i].Block) != 0 ||
   616  			c1.MaxCodeSizeConfig[i].Size != c2.MaxCodeSizeConfig[i].Size {
   617  			return errors.New("maxCodeSizeConfig data incompatible. maxCodeSize historical data does not match"), head, head
   618  		}
   619  	}
   620  
   621  	return nil, big.NewInt(0), big.NewInt(0)
   622  }
   623  
   624  // Quorum
   625  //
   626  // IsPrivacyEnhancementsEnabled returns whether num represents a block number after the PrivacyEnhancementsEnabled fork
   627  func (c *ChainConfig) IsPrivacyEnhancementsEnabled(num *big.Int) bool {
   628  	return isForked(c.PrivacyEnhancementsBlock, num)
   629  }
   630  
   631  // Quorum
   632  //
   633  // Check whether num represents a block number after the PrivacyPrecompileBlock
   634  func (c *ChainConfig) IsPrivacyPrecompile(num *big.Int) bool {
   635  	return isForked(c.PrivacyPrecompileBlock, num)
   636  }
   637  
   638  // CheckCompatible checks whether scheduled fork transitions have been imported
   639  // with a mismatching chain configuration.
   640  func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, isQuorumEIP155Activated bool) *ConfigCompatError {
   641  	bhead := new(big.Int).SetUint64(height)
   642  
   643  	// check if the maxCodesize data passed is compatible 1st
   644  	// this is being handled separately as it can have breaks
   645  	// at multiple block heights and cannot be handled with in
   646  	// checkCompatible
   647  
   648  	// compare the maxCodeSize data between the old and new config
   649  	err, cBlock, newCfgBlock := isMaxCodeSizeConfigCompatible(c, newcfg, bhead)
   650  	if err != nil {
   651  		return newCompatError(err.Error(), cBlock, newCfgBlock)
   652  	}
   653  
   654  	// Iterate checkCompatible to find the lowest conflict.
   655  	var lasterr *ConfigCompatError
   656  	for {
   657  		err := c.checkCompatible(newcfg, bhead, isQuorumEIP155Activated)
   658  		if err == nil || (lasterr != nil && err.RewindTo == lasterr.RewindTo) {
   659  			break
   660  		}
   661  		lasterr = err
   662  		bhead.SetUint64(err.RewindTo)
   663  	}
   664  	return lasterr
   665  }
   666  
   667  // CheckConfigForkOrder checks that we don't "skip" any forks, geth isn't pluggable enough
   668  // to guarantee that forks
   669  func (c *ChainConfig) CheckConfigForkOrder() error {
   670  	type fork struct {
   671  		name     string
   672  		block    *big.Int
   673  		optional bool // if true, the fork may be nil and next fork is still allowed
   674  	}
   675  	var lastFork fork
   676  	for _, cur := range []fork{
   677  		{name: "homesteadBlock", block: c.HomesteadBlock},
   678  		{name: "daoForkBlock", block: c.DAOForkBlock, optional: true},
   679  		{name: "eip150Block", block: c.EIP150Block},
   680  		{name: "eip155Block", block: c.EIP155Block},
   681  		{name: "eip158Block", block: c.EIP158Block},
   682  		{name: "byzantiumBlock", block: c.ByzantiumBlock},
   683  		{name: "constantinopleBlock", block: c.ConstantinopleBlock},
   684  		{name: "petersburgBlock", block: c.PetersburgBlock},
   685  		{name: "istanbulBlock", block: c.IstanbulBlock},
   686  		{name: "muirGlacierBlock", block: c.MuirGlacierBlock, optional: true},
   687  		{name: "yoloV2Block", block: c.YoloV2Block},
   688  	} {
   689  		if lastFork.name != "" {
   690  			// Next one must be higher number
   691  			if lastFork.block == nil && cur.block != nil {
   692  				return fmt.Errorf("unsupported fork ordering: %v not enabled, but %v enabled at %v",
   693  					lastFork.name, cur.name, cur.block)
   694  			}
   695  			if lastFork.block != nil && cur.block != nil {
   696  				if lastFork.block.Cmp(cur.block) > 0 {
   697  					return fmt.Errorf("unsupported fork ordering: %v enabled at %v, but %v enabled at %v",
   698  						lastFork.name, lastFork.block, cur.name, cur.block)
   699  				}
   700  			}
   701  		}
   702  		// If it was optional and not set, then ignore it
   703  		if !cur.optional || cur.block != nil {
   704  			lastFork = cur
   705  		}
   706  	}
   707  	return nil
   708  }
   709  
   710  func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int, isQuorumEIP155Activated bool) *ConfigCompatError {
   711  	if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) {
   712  		return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock)
   713  	}
   714  	if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) {
   715  		return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock)
   716  	}
   717  	if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport {
   718  		return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock)
   719  	}
   720  	if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) {
   721  		return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block)
   722  	}
   723  	if isQuorumEIP155Activated && c.ChainID != nil && isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) {
   724  		return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block)
   725  	}
   726  	if isQuorumEIP155Activated && c.ChainID != nil && c.IsEIP155(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   727  		return newCompatError("EIP155 chain ID", c.ChainID, newcfg.ChainID)
   728  	}
   729  	if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) {
   730  		return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block)
   731  	}
   732  	if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) {
   733  		return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block)
   734  	}
   735  	if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) {
   736  		return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock)
   737  	}
   738  	if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) {
   739  		return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock)
   740  	}
   741  	if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) {
   742  		// the only case where we allow Petersburg to be set in the past is if it is equal to Constantinople
   743  		// mainly to satisfy fork ordering requirements which state that Petersburg fork be set if Constantinople fork is set
   744  		if isForkIncompatible(c.ConstantinopleBlock, newcfg.PetersburgBlock, head) {
   745  			return newCompatError("Petersburg fork block", c.PetersburgBlock, newcfg.PetersburgBlock)
   746  		}
   747  	}
   748  	if isForkIncompatible(c.IstanbulBlock, newcfg.IstanbulBlock, head) {
   749  		return newCompatError("Istanbul fork block", c.IstanbulBlock, newcfg.IstanbulBlock)
   750  	}
   751  	if isForkIncompatible(c.MuirGlacierBlock, newcfg.MuirGlacierBlock, head) {
   752  		return newCompatError("Muir Glacier fork block", c.MuirGlacierBlock, newcfg.MuirGlacierBlock)
   753  	}
   754  	if isForkIncompatible(c.YoloV2Block, newcfg.YoloV2Block, head) {
   755  		return newCompatError("YOLOv2 fork block", c.YoloV2Block, newcfg.YoloV2Block)
   756  	}
   757  	if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) {
   758  		return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock)
   759  	}
   760  	if c.Istanbul != nil && newcfg.Istanbul != nil && isForkIncompatible(c.Istanbul.Ceil2Nby3Block, newcfg.Istanbul.Ceil2Nby3Block, head) {
   761  		return newCompatError("Ceil 2N/3 fork block", c.Istanbul.Ceil2Nby3Block, newcfg.Istanbul.Ceil2Nby3Block)
   762  	}
   763  	if c.Istanbul != nil && newcfg.Istanbul != nil && isForkIncompatible(c.Istanbul.TestQBFTBlock, newcfg.Istanbul.TestQBFTBlock, head) {
   764  		return newCompatError("Test QBFT fork block", c.Istanbul.TestQBFTBlock, newcfg.Istanbul.TestQBFTBlock)
   765  	}
   766  	if isForkIncompatible(c.QIP714Block, newcfg.QIP714Block, head) {
   767  		return newCompatError("permissions fork block", c.QIP714Block, newcfg.QIP714Block)
   768  	}
   769  	if newcfg.MaxCodeSizeChangeBlock != nil && isForkIncompatible(c.MaxCodeSizeChangeBlock, newcfg.MaxCodeSizeChangeBlock, head) {
   770  		return newCompatError("max code size change fork block", c.MaxCodeSizeChangeBlock, newcfg.MaxCodeSizeChangeBlock)
   771  	}
   772  	if isForkIncompatible(c.PrivacyEnhancementsBlock, newcfg.PrivacyEnhancementsBlock, head) {
   773  		return newCompatError("Privacy Enhancements fork block", c.PrivacyEnhancementsBlock, newcfg.PrivacyEnhancementsBlock)
   774  	}
   775  	if isForkIncompatible(c.PrivacyPrecompileBlock, newcfg.PrivacyPrecompileBlock, head) {
   776  		return newCompatError("Privacy Precompile fork block", c.PrivacyPrecompileBlock, newcfg.PrivacyPrecompileBlock)
   777  	}
   778  	return nil
   779  }
   780  
   781  // isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
   782  // block s2 because head is already past the fork.
   783  func isForkIncompatible(s1, s2, head *big.Int) bool {
   784  	return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2)
   785  }
   786  
   787  // isForked returns whether a fork scheduled at block s is active at the given head block.
   788  func isForked(s, head *big.Int) bool {
   789  	if s == nil || head == nil {
   790  		return false
   791  	}
   792  	return s.Cmp(head) <= 0
   793  }
   794  
   795  func configNumEqual(x, y *big.Int) bool {
   796  	if x == nil {
   797  		return y == nil
   798  	}
   799  	if y == nil {
   800  		return x == nil
   801  	}
   802  	return x.Cmp(y) == 0
   803  }
   804  
   805  // ConfigCompatError is raised if the locally-stored blockchain is initialised with a
   806  // ChainConfig that would alter the past.
   807  type ConfigCompatError struct {
   808  	What string
   809  	// block numbers of the stored and new configurations
   810  	StoredConfig, NewConfig *big.Int
   811  	// the block number to which the local chain must be rewound to correct the error
   812  	RewindTo uint64
   813  }
   814  
   815  func newCompatError(what string, storedblock, newblock *big.Int) *ConfigCompatError {
   816  	var rew *big.Int
   817  	switch {
   818  	case storedblock == nil:
   819  		rew = newblock
   820  	case newblock == nil || storedblock.Cmp(newblock) < 0:
   821  		rew = storedblock
   822  	default:
   823  		rew = newblock
   824  	}
   825  	err := &ConfigCompatError{what, storedblock, newblock, 0}
   826  	if rew != nil && rew.Sign() > 0 {
   827  		err.RewindTo = rew.Uint64() - 1
   828  	}
   829  	return err
   830  }
   831  
   832  func (err *ConfigCompatError) Error() string {
   833  	return fmt.Sprintf("mismatching %s in database (have %d, want %d, rewindto %d)", err.What, err.StoredConfig, err.NewConfig, err.RewindTo)
   834  }
   835  
   836  // Rules wraps ChainConfig and is merely syntactic sugar or can be used for functions
   837  // that do not have or require information about the block.
   838  //
   839  // Rules is a one time interface meaning that it shouldn't be used in between transition
   840  // phases.
   841  type Rules struct {
   842  	ChainID                                                 *big.Int
   843  	IsHomestead, IsEIP150, IsEIP155, IsEIP158               bool
   844  	IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool
   845  	IsYoloV2                                                bool
   846  	IsPrivacyEnhancementsEnabled                            bool // Quorum
   847  	IsPrivacyPrecompile                                     bool // Quorum
   848  }
   849  
   850  // Rules ensures c's ChainID is not nil.
   851  func (c *ChainConfig) Rules(num *big.Int) Rules {
   852  	chainID := c.ChainID
   853  	if chainID == nil {
   854  		chainID = new(big.Int)
   855  	}
   856  	return Rules{
   857  		ChainID:                      new(big.Int).Set(chainID),
   858  		IsHomestead:                  c.IsHomestead(num),
   859  		IsEIP150:                     c.IsEIP150(num),
   860  		IsEIP155:                     c.IsEIP155(num),
   861  		IsEIP158:                     c.IsEIP158(num),
   862  		IsByzantium:                  c.IsByzantium(num),
   863  		IsConstantinople:             c.IsConstantinople(num),
   864  		IsPetersburg:                 c.IsPetersburg(num),
   865  		IsIstanbul:                   c.IsIstanbul(num),
   866  		IsYoloV2:                     c.IsYoloV2(num),
   867  		IsPrivacyEnhancementsEnabled: c.IsPrivacyEnhancementsEnabled(num), // Quorum
   868  		IsPrivacyPrecompile:          c.IsPrivacyPrecompile(num),          // Quorum
   869  	}
   870  }