|
|
|
@ -7,145 +7,33 @@ import ( |
|
|
|
|
"github.com/ethereum/go-ethereum/common" |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// Genesis hashes to enforce below configs on.
|
|
|
|
|
var ( |
|
|
|
|
MainnetGenesisHash = common.HexToHash("0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3") |
|
|
|
|
TestnetGenesisHash = common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d") |
|
|
|
|
RinkebyGenesisHash = common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177") |
|
|
|
|
GoerliGenesisHash = common.HexToHash("0xbf7e331f7f7c1dd2e05159666b3bf8bc7a8a3a9eb1d518969eab529dd9b88c1a") |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// TrustedCheckpoints associates each known checkpoint with the genesis hash of
|
|
|
|
|
// the chain it belongs to.
|
|
|
|
|
var TrustedCheckpoints = map[common.Hash]*TrustedCheckpoint{ |
|
|
|
|
MainnetGenesisHash: MainnetTrustedCheckpoint, |
|
|
|
|
TestnetGenesisHash: TestnetTrustedCheckpoint, |
|
|
|
|
RinkebyGenesisHash: RinkebyTrustedCheckpoint, |
|
|
|
|
GoerliGenesisHash: GoerliTrustedCheckpoint, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var ( |
|
|
|
|
// MainnetChainConfig is the chain parameters to run a node on the main network.
|
|
|
|
|
MainnetChainConfig = &ChainConfig{ |
|
|
|
|
ChainID: big.NewInt(1), |
|
|
|
|
HomesteadBlock: big.NewInt(1150000), |
|
|
|
|
DAOForkBlock: big.NewInt(1920000), |
|
|
|
|
DAOForkSupport: true, |
|
|
|
|
EIP150Block: big.NewInt(2463000), |
|
|
|
|
EIP150Hash: common.HexToHash("0x2086799aeebeae135c246c65021c82b4e15a2c451340993aacfd2751886514f0"), |
|
|
|
|
EIP155Block: big.NewInt(2675000), |
|
|
|
|
EIP158Block: big.NewInt(2675000), |
|
|
|
|
ByzantiumBlock: big.NewInt(4370000), |
|
|
|
|
ConstantinopleBlock: big.NewInt(7280000), |
|
|
|
|
PetersburgBlock: big.NewInt(7280000), |
|
|
|
|
Ethash: new(EthashConfig), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// MainnetTrustedCheckpoint contains the light client trusted checkpoint for the main network.
|
|
|
|
|
MainnetTrustedCheckpoint = &TrustedCheckpoint{ |
|
|
|
|
Name: "mainnet", |
|
|
|
|
SectionIndex: 227, |
|
|
|
|
SectionHead: common.HexToHash("0xa2e0b25d72c2fc6e35a7f853cdacb193b4b4f95c606accf7f8fa8415283582c7"), |
|
|
|
|
CHTRoot: common.HexToHash("0xf69bdd4053b95b61a27b106a0e86103d791edd8574950dc96aa351ab9b9f1aa0"), |
|
|
|
|
BloomRoot: common.HexToHash("0xec1b454d4c6322c78ccedf76ac922a8698c3cac4d98748a84af4995b7bd3d744"), |
|
|
|
|
CrossLinkEpoch: big.NewInt(21), |
|
|
|
|
EIP155Epoch: big.NewInt(20), |
|
|
|
|
S3Epoch: big.NewInt(20), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestnetChainConfig contains the chain parameters to run a node on the Ropsten test network.
|
|
|
|
|
// TestnetChainConfig contains the chain parameters to run a node on the harmony test network.
|
|
|
|
|
TestnetChainConfig = &ChainConfig{ |
|
|
|
|
ChainID: big.NewInt(3), |
|
|
|
|
HomesteadBlock: big.NewInt(0), |
|
|
|
|
DAOForkBlock: nil, |
|
|
|
|
DAOForkSupport: true, |
|
|
|
|
EIP150Block: big.NewInt(0), |
|
|
|
|
EIP150Hash: common.HexToHash("0x41941023680923e0fe4d74a34bdac8141f2540e3ae90623718e47d66d1ca4a2d"), |
|
|
|
|
EIP155Block: big.NewInt(10), |
|
|
|
|
EIP158Block: big.NewInt(10), |
|
|
|
|
ByzantiumBlock: big.NewInt(1700000), |
|
|
|
|
ConstantinopleBlock: big.NewInt(4230000), |
|
|
|
|
PetersburgBlock: big.NewInt(4939394), |
|
|
|
|
Ethash: new(EthashConfig), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// TestnetTrustedCheckpoint contains the light client trusted checkpoint for the Ropsten test network.
|
|
|
|
|
TestnetTrustedCheckpoint = &TrustedCheckpoint{ |
|
|
|
|
Name: "testnet", |
|
|
|
|
SectionIndex: 161, |
|
|
|
|
SectionHead: common.HexToHash("0x5378afa734e1feafb34bcca1534c4d96952b754579b96a4afb23d5301ecececc"), |
|
|
|
|
CHTRoot: common.HexToHash("0x1cf2b071e7443a62914362486b613ff30f60cea0d9c268ed8c545f876a3ee60c"), |
|
|
|
|
BloomRoot: common.HexToHash("0x5ac25c84bd18a9cbe878d4609a80220f57f85037a112644532412ba0d498a31b"), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RinkebyChainConfig contains the chain parameters to run a node on the Rinkeby test network.
|
|
|
|
|
RinkebyChainConfig = &ChainConfig{ |
|
|
|
|
ChainID: big.NewInt(4), |
|
|
|
|
HomesteadBlock: big.NewInt(1), |
|
|
|
|
DAOForkBlock: nil, |
|
|
|
|
DAOForkSupport: true, |
|
|
|
|
EIP150Block: big.NewInt(2), |
|
|
|
|
EIP150Hash: common.HexToHash("0x9b095b36c15eaf13044373aef8ee0bd3a382a5abb92e402afa44b8249c3a90e9"), |
|
|
|
|
EIP155Block: big.NewInt(3), |
|
|
|
|
EIP158Block: big.NewInt(3), |
|
|
|
|
ByzantiumBlock: big.NewInt(1035301), |
|
|
|
|
ConstantinopleBlock: big.NewInt(3660663), |
|
|
|
|
PetersburgBlock: big.NewInt(4321234), |
|
|
|
|
Clique: &CliqueConfig{ |
|
|
|
|
Period: 15, |
|
|
|
|
Epoch: 30000, |
|
|
|
|
}, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// RinkebyTrustedCheckpoint contains the light client trusted checkpoint for the Rinkeby test network.
|
|
|
|
|
RinkebyTrustedCheckpoint = &TrustedCheckpoint{ |
|
|
|
|
Name: "rinkeby", |
|
|
|
|
SectionIndex: 125, |
|
|
|
|
SectionHead: common.HexToHash("0x8a738386f6bb34add15846f8f49c4c519a2f32519096e792b9f43bcb407c831c"), |
|
|
|
|
CHTRoot: common.HexToHash("0xa1e5720a9bad4dce794f129e4ac6744398197b652868011486a6f89c8ec84a75"), |
|
|
|
|
BloomRoot: common.HexToHash("0xa3048fe8b7e30f77f11bc755a88478363d7d3e71c2bdfe4e8ab9e269cd804ba2"), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GoerliChainConfig contains the chain parameters to run a node on the Görli test network.
|
|
|
|
|
GoerliChainConfig = &ChainConfig{ |
|
|
|
|
ChainID: big.NewInt(5), |
|
|
|
|
HomesteadBlock: big.NewInt(0), |
|
|
|
|
DAOForkBlock: nil, |
|
|
|
|
DAOForkSupport: true, |
|
|
|
|
EIP150Block: big.NewInt(0), |
|
|
|
|
EIP155Block: big.NewInt(0), |
|
|
|
|
EIP158Block: big.NewInt(0), |
|
|
|
|
ByzantiumBlock: big.NewInt(0), |
|
|
|
|
ConstantinopleBlock: big.NewInt(0), |
|
|
|
|
PetersburgBlock: big.NewInt(0), |
|
|
|
|
Clique: &CliqueConfig{ |
|
|
|
|
Period: 15, |
|
|
|
|
Epoch: 30000, |
|
|
|
|
}, |
|
|
|
|
ChainID: big.NewInt(2), |
|
|
|
|
CrossLinkEpoch: big.NewInt(0), |
|
|
|
|
EIP155Epoch: big.NewInt(0), |
|
|
|
|
S3Epoch: big.NewInt(0), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GoerliTrustedCheckpoint contains the light client trusted checkpoint for the Görli test network.
|
|
|
|
|
GoerliTrustedCheckpoint = &TrustedCheckpoint{ |
|
|
|
|
Name: "goerli", |
|
|
|
|
SectionIndex: 9, |
|
|
|
|
SectionHead: common.HexToHash("0x8e223d827391eee53b07cb8ee057dbfa11c93e0b45352188c783affd7840a921"), |
|
|
|
|
CHTRoot: common.HexToHash("0xe0a817ac69b36c1e437c5b0cff9e764853f5115702b5f66d451b665d6afb7e78"), |
|
|
|
|
BloomRoot: common.HexToHash("0x50d672aeb655b723284969c7c1201fb6ca003c23ed144bcb9f2d1b30e2971c1b"), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// AllEthashProtocolChanges contains every protocol change (EIPs) introduced
|
|
|
|
|
// and accepted by the Ethereum core developers into the Ethash consensus.
|
|
|
|
|
//
|
|
|
|
|
// AllProtocolChanges ...
|
|
|
|
|
// This configuration is intentionally not using keyed fields to force anyone
|
|
|
|
|
// adding flags to the config to also have to set these fields.
|
|
|
|
|
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), nil, new(EthashConfig), nil} |
|
|
|
|
AllProtocolChanges = &ChainConfig{big.NewInt(100), big.NewInt(0), big.NewInt(0), big.NewInt(0)} |
|
|
|
|
|
|
|
|
|
// AllCliqueProtocolChanges contains every protocol change (EIPs) introduced
|
|
|
|
|
// and accepted by the Ethereum core developers into the Clique consensus.
|
|
|
|
|
//
|
|
|
|
|
// TestChainConfig ...
|
|
|
|
|
// This configuration is intentionally not using keyed fields to force anyone
|
|
|
|
|
// adding flags to the config to also have to set these fields.
|
|
|
|
|
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), nil, nil, &CliqueConfig{Period: 0, Epoch: 30000}} |
|
|
|
|
TestChainConfig = &ChainConfig{big.NewInt(99), big.NewInt(0), big.NewInt(0), big.NewInt(0)} |
|
|
|
|
|
|
|
|
|
// TestChainConfig ...
|
|
|
|
|
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), nil, new(EthashConfig), nil} |
|
|
|
|
// TestRules ...
|
|
|
|
|
TestRules = TestChainConfig.Rules(new(big.Int)) |
|
|
|
|
) |
|
|
|
@ -170,136 +58,48 @@ type TrustedCheckpoint struct { |
|
|
|
|
type ChainConfig struct { |
|
|
|
|
ChainID *big.Int `json:"chainId"` // chainId identifies the current chain and is used for replay protection
|
|
|
|
|
|
|
|
|
|
HomesteadBlock *big.Int `json:"homesteadBlock,omitempty"` // Homestead switch block (nil = no fork, 0 = already homestead)
|
|
|
|
|
|
|
|
|
|
DAOForkBlock *big.Int `json:"daoForkBlock,omitempty"` // TheDAO hard-fork switch block (nil = no fork)
|
|
|
|
|
DAOForkSupport bool `json:"daoForkSupport,omitempty"` // Whether the nodes supports or opposes the DAO hard-fork
|
|
|
|
|
|
|
|
|
|
// EIP150 implements the Gas price changes (https://github.com/ethereum/EIPs/issues/150)
|
|
|
|
|
EIP150Block *big.Int `json:"eip150Block,omitempty"` // EIP150 HF block (nil = no fork)
|
|
|
|
|
EIP150Hash common.Hash `json:"eip150Hash,omitempty"` // EIP150 HF hash (needed for header only clients as only gas pricing changed)
|
|
|
|
|
|
|
|
|
|
EIP155Block *big.Int `json:"eip155Block,omitempty"` // EIP155 HF block
|
|
|
|
|
EIP158Block *big.Int `json:"eip158Block,omitempty"` // EIP158 HF block
|
|
|
|
|
|
|
|
|
|
ByzantiumBlock *big.Int `json:"byzantiumBlock,omitempty"` // Byzantium switch block (nil = no fork, 0 = already on byzantium)
|
|
|
|
|
ConstantinopleBlock *big.Int `json:"constantinopleBlock,omitempty"` // Constantinople switch block (nil = no fork, 0 = already activated)
|
|
|
|
|
PetersburgBlock *big.Int `json:"petersburgBlock,omitempty"` // Petersburg switch block (nil = same as Constantinople)
|
|
|
|
|
EWASMBlock *big.Int `json:"ewasmBlock,omitempty"` // EWASM switch block (nil = no fork, 0 = already activated)
|
|
|
|
|
|
|
|
|
|
// Various consensus engines
|
|
|
|
|
Ethash *EthashConfig `json:"ethash,omitempty"` |
|
|
|
|
Clique *CliqueConfig `json:"clique,omitempty"` |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// EthashConfig is the consensus engine configs for proof-of-work based sealing.
|
|
|
|
|
type EthashConfig struct{} |
|
|
|
|
|
|
|
|
|
// String implements the stringer interface, returning the consensus engine details.
|
|
|
|
|
func (c *EthashConfig) String() string { |
|
|
|
|
return "ethash" |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// CliqueConfig is the consensus engine configs for proof-of-authority based sealing.
|
|
|
|
|
type CliqueConfig struct { |
|
|
|
|
Period uint64 `json:"period"` // Number of seconds between blocks to enforce
|
|
|
|
|
Epoch uint64 `json:"epoch"` // Epoch length to reset votes and checkpoint
|
|
|
|
|
} |
|
|
|
|
CrossLinkEpoch *big.Int `json:"crossLinkEpoch,omitempty"` |
|
|
|
|
|
|
|
|
|
// String implements the stringer interface, returning the consensus engine details.
|
|
|
|
|
func (c *CliqueConfig) String() string { |
|
|
|
|
return "clique" |
|
|
|
|
EIP155Epoch *big.Int `json:"eip155Epoch,omitempty"` // EIP155 hard fork epoch (include EIP158 too)
|
|
|
|
|
S3Epoch *big.Int `json:"s3Epoch,omitempty"` // S3 epoch is the first epoch containing S3 mainnet and all ethereum update up to Constantinople
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// String implements the fmt.Stringer interface.
|
|
|
|
|
func (c *ChainConfig) String() string { |
|
|
|
|
var engine interface{} |
|
|
|
|
switch { |
|
|
|
|
case c.Ethash != nil: |
|
|
|
|
engine = c.Ethash |
|
|
|
|
case c.Clique != nil: |
|
|
|
|
engine = c.Clique |
|
|
|
|
default: |
|
|
|
|
engine = "unknown" |
|
|
|
|
} |
|
|
|
|
return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v ConstantinopleFix: %v Engine: %v}", |
|
|
|
|
return fmt.Sprintf("{ChainID: %v EIP155: %v CrossLink: %v}", |
|
|
|
|
c.ChainID, |
|
|
|
|
c.HomesteadBlock, |
|
|
|
|
c.DAOForkBlock, |
|
|
|
|
c.DAOForkSupport, |
|
|
|
|
c.EIP150Block, |
|
|
|
|
c.EIP155Block, |
|
|
|
|
c.EIP158Block, |
|
|
|
|
c.ByzantiumBlock, |
|
|
|
|
c.ConstantinopleBlock, |
|
|
|
|
c.PetersburgBlock, |
|
|
|
|
engine, |
|
|
|
|
c.CrossLinkEpoch, |
|
|
|
|
c.EIP155Epoch, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsHomestead returns whether num is either equal to the homestead block or greater.
|
|
|
|
|
func (c *ChainConfig) IsHomestead(num *big.Int) bool { |
|
|
|
|
return isForked(c.HomesteadBlock, num) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsDAOFork returns whether num is either equal to the DAO fork block or greater.
|
|
|
|
|
func (c *ChainConfig) IsDAOFork(num *big.Int) bool { |
|
|
|
|
return isForked(c.DAOForkBlock, num) |
|
|
|
|
// IsEIP155 returns whether epoch is either equal to the EIP155 fork epoch or greater.
|
|
|
|
|
func (c *ChainConfig) IsEIP155(epoch *big.Int) bool { |
|
|
|
|
return isForked(c.EIP155Epoch, epoch) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsEIP150 returns whether num is either equal to the EIP150 fork block or greater.
|
|
|
|
|
func (c *ChainConfig) IsEIP150(num *big.Int) bool { |
|
|
|
|
return isForked(c.EIP150Block, num) |
|
|
|
|
// IsCrossLink returns whether epoch is either equal to the CrossLink fork epoch or greater.
|
|
|
|
|
func (c *ChainConfig) IsCrossLink(epoch *big.Int) bool { |
|
|
|
|
return isForked(c.CrossLinkEpoch, epoch) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsEIP155 returns whether num is either equal to the EIP155 fork block or greater.
|
|
|
|
|
func (c *ChainConfig) IsEIP155(num *big.Int) bool { |
|
|
|
|
return isForked(c.EIP155Block, num) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsEIP158 returns whether num is either equal to the EIP158 fork block or greater.
|
|
|
|
|
func (c *ChainConfig) IsEIP158(num *big.Int) bool { |
|
|
|
|
return isForked(c.EIP158Block, num) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsByzantium returns whether num is either equal to the Byzantium fork block or greater.
|
|
|
|
|
func (c *ChainConfig) IsByzantium(num *big.Int) bool { |
|
|
|
|
return isForked(c.ByzantiumBlock, num) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsConstantinople returns whether num is either equal to the Constantinople fork block or greater.
|
|
|
|
|
func (c *ChainConfig) IsConstantinople(num *big.Int) bool { |
|
|
|
|
return isForked(c.ConstantinopleBlock, num) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsPetersburg returns whether num is either
|
|
|
|
|
// - equal to or greater than the PetersburgBlock fork block,
|
|
|
|
|
// - OR is nil, and Constantinople is active
|
|
|
|
|
func (c *ChainConfig) IsPetersburg(num *big.Int) bool { |
|
|
|
|
return isForked(c.PetersburgBlock, num) || c.PetersburgBlock == nil && isForked(c.ConstantinopleBlock, num) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// IsEWASM returns whether num represents a block number after the EWASM fork
|
|
|
|
|
func (c *ChainConfig) IsEWASM(num *big.Int) bool { |
|
|
|
|
return isForked(c.EWASMBlock, num) |
|
|
|
|
// IsS3 returns whether epoch is either equal to the S3 fork epoch or greater.
|
|
|
|
|
func (c *ChainConfig) IsS3(epoch *big.Int) bool { |
|
|
|
|
return isForked(c.CrossLinkEpoch, epoch) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GasTable returns the gas table corresponding to the current phase (homestead or homestead reprice).
|
|
|
|
|
//
|
|
|
|
|
// The returned GasTable's fields shouldn't, under any circumstances, be changed.
|
|
|
|
|
func (c *ChainConfig) GasTable(num *big.Int) GasTable { |
|
|
|
|
if num == nil { |
|
|
|
|
return GasTableHomestead |
|
|
|
|
func (c *ChainConfig) GasTable(epoch *big.Int) GasTable { |
|
|
|
|
if epoch == nil { |
|
|
|
|
return GasTableR3 |
|
|
|
|
} |
|
|
|
|
switch { |
|
|
|
|
case c.IsConstantinople(num): |
|
|
|
|
return GasTableConstantinople |
|
|
|
|
case c.IsEIP158(num): |
|
|
|
|
return GasTableEIP158 |
|
|
|
|
case c.IsEIP150(num): |
|
|
|
|
return GasTableEIP150 |
|
|
|
|
case c.IsS3(epoch): |
|
|
|
|
return GasTableS3 |
|
|
|
|
default: |
|
|
|
|
return GasTableHomestead |
|
|
|
|
return GasTableR3 |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -322,54 +122,31 @@ func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *Confi |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *ConfigCompatError { |
|
|
|
|
if isForkIncompatible(c.HomesteadBlock, newcfg.HomesteadBlock, head) { |
|
|
|
|
return newCompatError("Homestead fork block", c.HomesteadBlock, newcfg.HomesteadBlock) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.DAOForkBlock, newcfg.DAOForkBlock, head) { |
|
|
|
|
return newCompatError("DAO fork block", c.DAOForkBlock, newcfg.DAOForkBlock) |
|
|
|
|
} |
|
|
|
|
if c.IsDAOFork(head) && c.DAOForkSupport != newcfg.DAOForkSupport { |
|
|
|
|
return newCompatError("DAO fork support flag", c.DAOForkBlock, newcfg.DAOForkBlock) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.EIP150Block, newcfg.EIP150Block, head) { |
|
|
|
|
return newCompatError("EIP150 fork block", c.EIP150Block, newcfg.EIP150Block) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.EIP155Block, newcfg.EIP155Block, head) { |
|
|
|
|
return newCompatError("EIP155 fork block", c.EIP155Block, newcfg.EIP155Block) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.EIP158Block, newcfg.EIP158Block, head) { |
|
|
|
|
return newCompatError("EIP158 fork block", c.EIP158Block, newcfg.EIP158Block) |
|
|
|
|
} |
|
|
|
|
if c.IsEIP158(head) && !configNumEqual(c.ChainID, newcfg.ChainID) { |
|
|
|
|
return newCompatError("EIP158 chain ID", c.EIP158Block, newcfg.EIP158Block) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.ByzantiumBlock, newcfg.ByzantiumBlock, head) { |
|
|
|
|
return newCompatError("Byzantium fork block", c.ByzantiumBlock, newcfg.ByzantiumBlock) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.ConstantinopleBlock, newcfg.ConstantinopleBlock, head) { |
|
|
|
|
return newCompatError("Constantinople fork block", c.ConstantinopleBlock, newcfg.ConstantinopleBlock) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.PetersburgBlock, newcfg.PetersburgBlock, head) { |
|
|
|
|
return newCompatError("ConstantinopleFix fork block", c.PetersburgBlock, newcfg.PetersburgBlock) |
|
|
|
|
} |
|
|
|
|
if isForkIncompatible(c.EWASMBlock, newcfg.EWASMBlock, head) { |
|
|
|
|
return newCompatError("ewasm fork block", c.EWASMBlock, newcfg.EWASMBlock) |
|
|
|
|
} |
|
|
|
|
// TODO: check compatibility and reversion based on epochs.
|
|
|
|
|
//if isForkIncompatible(c.EIP155Epoch, newcfg.EIP155Epoch, head) {
|
|
|
|
|
// return newCompatError("EIP155 fork block", c.EIP155Epoch, newcfg.EIP155Epoch)
|
|
|
|
|
//}
|
|
|
|
|
//if isForkIncompatible(c.CrossLinkEpoch, newcfg.CrossLinkEpoch, head) {
|
|
|
|
|
// return newCompatError("CrossLink fork block", c.CrossLinkEpoch, newcfg.CrossLinkEpoch)
|
|
|
|
|
//}
|
|
|
|
|
//if isForkIncompatible(c.S3Epoch, newcfg.S3Epoch, head) {
|
|
|
|
|
// return newCompatError("S3 fork block", c.S3Epoch, newcfg.S3Epoch)
|
|
|
|
|
//}
|
|
|
|
|
return nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// isForkIncompatible returns true if a fork scheduled at s1 cannot be rescheduled to
|
|
|
|
|
// block s2 because head is already past the fork.
|
|
|
|
|
func isForkIncompatible(s1, s2, head *big.Int) bool { |
|
|
|
|
return (isForked(s1, head) || isForked(s2, head)) && !configNumEqual(s1, s2) |
|
|
|
|
// epoch s2 because head is already past the fork.
|
|
|
|
|
func isForkIncompatible(s1, s2, epoch *big.Int) bool { |
|
|
|
|
return (isForked(s1, epoch) || isForked(s2, epoch)) && !configNumEqual(s1, s2) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// isForked returns whether a fork scheduled at block s is active at the given head block.
|
|
|
|
|
func isForked(s, head *big.Int) bool { |
|
|
|
|
if s == nil || head == nil { |
|
|
|
|
// isForked returns whether a fork scheduled at epoch s is active at the given head epoch.
|
|
|
|
|
func isForked(s, epoch *big.Int) bool { |
|
|
|
|
if s == nil || epoch == nil { |
|
|
|
|
return false |
|
|
|
|
} |
|
|
|
|
return s.Cmp(head) <= 0 |
|
|
|
|
return s.Cmp(epoch) <= 0 |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
func configNumEqual(x, y *big.Int) bool { |
|
|
|
@ -420,24 +197,19 @@ func (err *ConfigCompatError) Error() string { |
|
|
|
|
// phases.
|
|
|
|
|
type Rules struct { |
|
|
|
|
ChainID *big.Int |
|
|
|
|
IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool |
|
|
|
|
IsByzantium, IsConstantinople, IsPetersburg bool |
|
|
|
|
IsCrossLink, IsEIP155, IsS3 bool |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Rules ensures c's ChainID is not nil.
|
|
|
|
|
func (c *ChainConfig) Rules(num *big.Int) Rules { |
|
|
|
|
func (c *ChainConfig) Rules(epoch *big.Int) Rules { |
|
|
|
|
chainID := c.ChainID |
|
|
|
|
if chainID == nil { |
|
|
|
|
chainID = new(big.Int) |
|
|
|
|
} |
|
|
|
|
return Rules{ |
|
|
|
|
ChainID: new(big.Int).Set(chainID), |
|
|
|
|
IsHomestead: c.IsHomestead(num), |
|
|
|
|
IsEIP150: c.IsEIP150(num), |
|
|
|
|
IsEIP155: c.IsEIP155(num), |
|
|
|
|
IsEIP158: c.IsEIP158(num), |
|
|
|
|
IsByzantium: c.IsByzantium(num), |
|
|
|
|
IsConstantinople: c.IsConstantinople(num), |
|
|
|
|
IsPetersburg: c.IsPetersburg(num), |
|
|
|
|
IsCrossLink: c.IsCrossLink(epoch), |
|
|
|
|
IsEIP155: c.IsEIP155(epoch), |
|
|
|
|
IsS3: c.IsS3(epoch), |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|