diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index 4e8b4f411..7d6e89c81 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -387,10 +387,10 @@ func TestValidation(t *testing.T) { // TODO(karalabe): Enable this when Cancun is specced, update local head and time, next timestamp //{×tampedConfig, 21123456, 1678123456, ID{Hash: checksumToBytes(0x71147644), Next: 1678000000}, nil}, - // Local is mainnet Osaka, remote announces Shanghai + knowledge about Cancun. Remote - // is definitely out of sync. It may or may not need the Osaka update, we don't know yet. + // Local is mainnet Prague, remote announces Shanghai + knowledge about Cancun. Remote + // is definitely out of sync. It may or may not need the Prague update, we don't know yet. // - // TODO(karalabe): Enable this when Cancun **and** Osaka is specced, update all the numbers + // TODO(karalabe): Enable this when Cancun **and** Prague is specced, update all the numbers //{×tampedConfig, 0, 0, ID{Hash: checksumToBytes(0x3edd5b10), Next: 4370000}, nil}, // Local is mainnet Shanghai, remote announces Cancun. Local is out of sync, accept. @@ -398,10 +398,10 @@ func TestValidation(t *testing.T) { // TODO(karalabe): Enable this when Cancun is specced, update remote checksum //{×tampedConfig, 21000000, 1678000000, ID{Hash: checksumToBytes(0x00000000), Next: 0}, nil}, - // Local is mainnet Shanghai, remote announces Cancun, but is not aware of Osaka. Local + // Local is mainnet Shanghai, remote announces Cancun, but is not aware of Prague. Local // out of sync. Local also knows about a future fork, but that is uncertain yet. // - // TODO(karalabe): Enable this when Cancun **and** Osaka is specced, update remote checksum + // TODO(karalabe): Enable this when Cancun **and** Prague is specced, update remote checksum //{×tampedConfig, 21000000, 1678000000, ID{Hash: checksumToBytes(0x00000000), Next: 0}, nil}, // Local is mainnet Cancun. remote announces Shanghai but is not aware of further forks. diff --git a/params/config.go b/params/config.go index 9c9942f8b..41072d3ea 100644 --- a/params/config.go +++ b/params/config.go @@ -266,21 +266,124 @@ var ( // AllEthashProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Ethash consensus. - // - // 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, new(EthashConfig), nil} + AllEthashProtocolChanges = &ChainConfig{ + ChainID: big.NewInt(1337), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: false, + EIP150Block: big.NewInt(0), + EIP150Hash: common.Hash{}, + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + GrayGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: nil, + ShanghaiTime: nil, + CancunTime: nil, + PragueTime: nil, + TerminalTotalDifficulty: nil, + TerminalTotalDifficultyPassed: false, + Ethash: new(EthashConfig), + Clique: nil, + } // AllCliqueProtocolChanges contains every protocol change (EIPs) introduced // and accepted by the Ethereum core developers into the Clique consensus. - // - // 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), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, nil, nil, false, nil, &CliqueConfig{Period: 0, Epoch: 30000}} + AllCliqueProtocolChanges = &ChainConfig{ + ChainID: big.NewInt(1337), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: false, + EIP150Block: big.NewInt(0), + EIP150Hash: common.Hash{}, + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: nil, + GrayGlacierBlock: nil, + MergeNetsplitBlock: nil, + ShanghaiTime: nil, + CancunTime: nil, + PragueTime: nil, + TerminalTotalDifficulty: nil, + TerminalTotalDifficultyPassed: false, + Ethash: nil, + Clique: &CliqueConfig{Period: 0, Epoch: 30000}, + } - 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), big.NewInt(0), big.NewInt(0), nil, nil, nil, nil, false, new(EthashConfig), nil} - NonActivatedConfig = &ChainConfig{big.NewInt(1), nil, nil, false, nil, common.Hash{}, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, false, new(EthashConfig), nil} - TestRules = TestChainConfig.Rules(new(big.Int), false, new(big.Int)) + // TestChainConfig contains every protocol change (EIPs) introduced + // and accepted by the Ethereum core developers for testing proposes. + TestChainConfig = &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: false, + EIP150Block: big.NewInt(0), + EIP150Hash: common.Hash{}, + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + GrayGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: nil, + ShanghaiTime: nil, + CancunTime: nil, + PragueTime: nil, + TerminalTotalDifficulty: nil, + TerminalTotalDifficultyPassed: false, + Ethash: new(EthashConfig), + Clique: nil, + } + + // NonActivatedConfig defines the chain configuration without activating + // any protocol change (EIPs). + NonActivatedConfig = &ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: nil, + DAOForkBlock: nil, + DAOForkSupport: false, + EIP150Block: nil, + EIP150Hash: common.Hash{}, + EIP155Block: nil, + EIP158Block: nil, + ByzantiumBlock: nil, + ConstantinopleBlock: nil, + PetersburgBlock: nil, + IstanbulBlock: nil, + MuirGlacierBlock: nil, + BerlinBlock: nil, + LondonBlock: nil, + ArrowGlacierBlock: nil, + GrayGlacierBlock: nil, + MergeNetsplitBlock: nil, + ShanghaiTime: nil, + CancunTime: nil, + PragueTime: nil, + TerminalTotalDifficulty: nil, + TerminalTotalDifficultyPassed: false, + Ethash: new(EthashConfig), + Clique: nil, + } + TestRules = TestChainConfig.Rules(new(big.Int), false, new(big.Int)) ) // NetworkNames are user friendly names to use in the chain spec banner. @@ -370,11 +473,12 @@ type ChainConfig struct { ArrowGlacierBlock *big.Int `json:"arrowGlacierBlock,omitempty"` // Eip-4345 (bomb delay) switch block (nil = no fork, 0 = already activated) GrayGlacierBlock *big.Int `json:"grayGlacierBlock,omitempty"` // Eip-5133 (bomb delay) switch block (nil = no fork, 0 = already activated) MergeNetsplitBlock *big.Int `json:"mergeNetsplitBlock,omitempty"` // Virtual fork after The Merge to use as a network splitter - CancunBlock *big.Int `json:"cancunBlock,omitempty"` // Cancun switch block (nil = no fork, 0 = already on cancun) // Fork scheduling was switched from blocks to timestamps here ShanghaiTime *big.Int `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) + CancunTime *big.Int `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) + PragueTime *big.Int `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -489,8 +593,11 @@ func (c *ChainConfig) Description() string { if c.ShanghaiTime != nil { banner += fmt.Sprintf(" - Shanghai: @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md)\n", c.ShanghaiTime) } - if c.CancunBlock != nil { - banner += fmt.Sprintf(" - Cancun: @%-10v\n", c.CancunBlock) + if c.CancunTime != nil { + banner += fmt.Sprintf(" - Cancun: @%-10v\n", c.CancunTime) + } + if c.PragueTime != nil { + banner += fmt.Sprintf(" - Prague: @%-10v\n", c.PragueTime) } return banner } @@ -575,16 +682,21 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 } -// IsCancun returns whether num is either equal to the Cancun fork block or greater. -func (c *ChainConfig) IsCancun(num *big.Int) bool { - return isBlockForked(c.CancunBlock, num) -} - // IsShanghai returns whether time is either equal to the Shanghai fork time or greater. func (c *ChainConfig) IsShanghai(time *big.Int) bool { return isTimestampForked(c.ShanghaiTime, time) } +// IsCancun returns whether num is either equal to the Cancun fork time or greater. +func (c *ChainConfig) IsCancun(time *big.Int) bool { + return isTimestampForked(c.CancunTime, time) +} + +// IsPrague returns whether num is either equal to the Prague fork time or greater. +func (c *ChainConfig) IsPrague(time *big.Int) bool { + return isTimestampForked(c.PragueTime, time) +} + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64, time uint64) *ConfigCompatError { @@ -636,8 +748,9 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "arrowGlacierBlock", block: c.ArrowGlacierBlock, optional: true}, {name: "grayGlacierBlock", block: c.GrayGlacierBlock, optional: true}, {name: "mergeNetsplitBlock", block: c.MergeNetsplitBlock, optional: true}, - {name: "cancunBlock", block: c.CancunBlock, optional: true}, {name: "shanghaiTime", timestamp: c.ShanghaiTime}, + {name: "cancunTime", timestamp: c.CancunTime, optional: true}, + {name: "pragueTime", timestamp: c.PragueTime, optional: true}, } { if lastFork.name != "" { switch { @@ -732,12 +845,15 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, if isForkBlockIncompatible(c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock, headNumber) { return newBlockCompatError("Merge netsplit fork block", c.MergeNetsplitBlock, newcfg.MergeNetsplitBlock) } - if isForkBlockIncompatible(c.CancunBlock, newcfg.CancunBlock, headNumber) { - return newBlockCompatError("Cancun fork block", c.CancunBlock, newcfg.CancunBlock) - } if isForkTimestampIncompatible(c.ShanghaiTime, newcfg.ShanghaiTime, headTimestamp) { return newTimestampCompatError("Shanghai fork timestamp", c.ShanghaiTime, newcfg.ShanghaiTime) } + if isForkTimestampIncompatible(c.CancunTime, newcfg.CancunTime, headTimestamp) { + return newTimestampCompatError("Cancun fork timestamp", c.CancunTime, newcfg.CancunTime) + } + if isForkTimestampIncompatible(c.PragueTime, newcfg.PragueTime, headTimestamp) { + return newTimestampCompatError("Prague fork timestamp", c.PragueTime, newcfg.PragueTime) + } return nil } @@ -882,7 +998,7 @@ type Rules struct { IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool - IsMerge, IsShanghai, isCancun bool + IsMerge, IsShanghai, isCancun, isPrague bool } // Rules ensures c's ChainID is not nil. @@ -905,6 +1021,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp *big.Int) Rule IsLondon: c.IsLondon(num), IsMerge: isMerge, IsShanghai: c.IsShanghai(timestamp), - isCancun: c.IsCancun(num), + isCancun: c.IsCancun(timestamp), + isPrague: c.IsPrague(timestamp), } }