diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 3132fbd95f..1958a88ba5 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -179,6 +179,25 @@ var PrecompiledContractsPlato = map[common.Address]PrecompiledContract{ common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{}, } +// PrecompiledContractsHertz contains the default set of pre-compiled Ethereum +// contracts used in the Hertz release. +var PrecompiledContractsHertz = map[common.Address]PrecompiledContract{ + common.BytesToAddress([]byte{1}): &ecrecover{}, + common.BytesToAddress([]byte{2}): &sha256hash{}, + common.BytesToAddress([]byte{3}): &ripemd160hash{}, + common.BytesToAddress([]byte{4}): &dataCopy{}, + common.BytesToAddress([]byte{5}): &bigModExp{eip2565: true}, + common.BytesToAddress([]byte{6}): &bn256AddIstanbul{}, + common.BytesToAddress([]byte{7}): &bn256ScalarMulIstanbul{}, + common.BytesToAddress([]byte{8}): &bn256PairingIstanbul{}, + common.BytesToAddress([]byte{9}): &blake2F{}, + + common.BytesToAddress([]byte{100}): &tmHeaderValidate{}, + common.BytesToAddress([]byte{101}): &iavlMerkleProofValidatePlato{}, + common.BytesToAddress([]byte{102}): &blsSignatureVerify{}, + common.BytesToAddress([]byte{103}): &cometBFTLightBlockValidate{}, +} + // PrecompiledContractsBLS contains the set of pre-compiled Ethereum // contracts specified in EIP-2537. These are exported for testing purposes. var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ @@ -194,6 +213,7 @@ var PrecompiledContractsBLS = map[common.Address]PrecompiledContract{ } var ( + PrecompiledAddressesHertz []common.Address PrecompiledAddressesPlato []common.Address PrecompiledAddressesLuban []common.Address PrecompiledAddressesPlanck []common.Address @@ -233,11 +253,16 @@ func init() { for k := range PrecompiledContractsPlato { PrecompiledAddressesPlato = append(PrecompiledAddressesPlato, k) } + for k := range PrecompiledContractsHertz { + PrecompiledAddressesHertz = append(PrecompiledAddressesHertz, k) + } } // ActivePrecompiles returns the precompiles enabled with the current configuration. func ActivePrecompiles(rules params.Rules) []common.Address { switch { + case rules.IsHertz: + return PrecompiledAddressesHertz case rules.IsPlato: return PrecompiledAddressesPlato case rules.IsLuban: diff --git a/core/vm/evm.go b/core/vm/evm.go index ae33238105..1d2beff18c 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -51,6 +51,8 @@ type ( func (evm *EVM) precompile(addr common.Address) (PrecompiledContract, bool) { var precompiles map[common.Address]PrecompiledContract switch { + case evm.chainRules.IsHertz: + precompiles = PrecompiledContractsHertz case evm.chainRules.IsPlato: precompiles = PrecompiledContractsPlato case evm.chainRules.IsLuban: diff --git a/eth/gasprice/gasprice_test.go b/eth/gasprice/gasprice_test.go index 2820cc683d..f2a0eb68fd 100644 --- a/eth/gasprice/gasprice_test.go +++ b/eth/gasprice/gasprice_test.go @@ -138,6 +138,7 @@ func newTestBackend(t *testing.T, londonBlock *big.Int, pending bool) *testBacke config.GibbsBlock = nil config.LubanBlock = nil config.PlatoBlock = nil + config.HertzBlock = nil engine := ethash.NewFaker() db := rawdb.NewMemoryDatabase() genesis, err := gspec.Commit(db) diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 0144332e1c..48b487c874 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -110,6 +110,7 @@ func testForkIDSplit(t *testing.T, protocol uint) { MoranBlock: big.NewInt(5), LubanBlock: big.NewInt(6), PlatoBlock: big.NewInt(6), + HertzBlock: big.NewInt(7), } dbNoFork = rawdb.NewMemoryDatabase() dbProFork = rawdb.NewMemoryDatabase() diff --git a/params/config.go b/params/config.go index 9883968446..5cd772c8d0 100644 --- a/params/config.go +++ b/params/config.go @@ -194,6 +194,9 @@ var ( // TODO Caution !!! it should be very careful !!! LubanBlock: nil, PlatoBlock: nil, + // TODO modify blockNumber, make sure the Hertz block number is equal to BerlinBlock for enabling Berlin EIPs + BerlinBlock: nil, + HertzBlock: nil, Parlia: &ParliaConfig{ Period: 3, @@ -224,8 +227,10 @@ var ( // TODO modify blockNumber, make sure the blockNumber is not an integer multiple of 200 (epoch number) // TODO Caution !!! it should be very careful !!! - LubanBlock: big.NewInt(29295050), - PlatoBlock: big.NewInt(29861024), + LubanBlock: big.NewInt(29295050), + PlatoBlock: big.NewInt(29861024), + BerlinBlock: nil, + HertzBlock: nil, Parlia: &ParliaConfig{ Period: 3, @@ -255,8 +260,10 @@ var ( PlanckBlock: nil, // TODO - LubanBlock: nil, - PlatoBlock: nil, + LubanBlock: nil, + PlatoBlock: nil, + BerlinBlock: nil, + HertzBlock: nil, Parlia: &ParliaConfig{ Period: 3, @@ -270,16 +277,16 @@ var ( // 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), big.NewInt(0), nil, nil, 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), new(EthashConfig), nil, nil} + 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), big.NewInt(0), nil, nil, 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), big.NewInt(0), new(EthashConfig), nil, 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), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} + 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), nil, nil, big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, &CliqueConfig{Period: 0, Epoch: 30000}, nil} - 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), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} + 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), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, big.NewInt(0), big.NewInt(0), big.NewInt(0), new(EthashConfig), nil, nil} TestRules = TestChainConfig.Rules(new(big.Int), false) ) @@ -378,6 +385,7 @@ type ChainConfig struct { PlanckBlock *big.Int `json:"planckBlock,omitempty" toml:",omitempty"` // planckBlock switch block (nil = no fork, 0 = already activated) LubanBlock *big.Int `json:"lubanBlock,omitempty" toml:",omitempty"` // lubanBlock switch block (nil = no fork, 0 = already activated) PlatoBlock *big.Int `json:"platoBlock,omitempty" toml:",omitempty"` // platoBlock switch block (nil = no fork, 0 = already activated) + HertzBlock *big.Int `json:"hertzBlock,omitempty" toml:",omitempty"` // hertzBlock switch block (nil = no fork, 0 = already activated) // Various consensus engines Ethash *EthashConfig `json:"ethash,omitempty" toml:",omitempty"` @@ -429,7 +437,7 @@ func (c *ChainConfig) String() string { engine = "unknown" } - 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, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Engine: %v}", + 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, Ramanujan: %v, Niels: %v, MirrorSync: %v, Bruno: %v, Berlin: %v, YOLO v3: %v, CatalystBlock: %v, London: %v, ArrowGlacier: %v, MergeFork:%v, Euler: %v, Gibbs: %v, Nano: %v, Moran: %v, Planck: %v,Luban: %v, Plato: %v, Hertz: %v, Engine: %v}", c.ChainID, c.HomesteadBlock, c.DAOForkBlock, @@ -459,6 +467,7 @@ func (c *ChainConfig) String() string { c.PlanckBlock, c.LubanBlock, c.PlatoBlock, + c.HertzBlock, engine, ) } @@ -568,6 +577,16 @@ func (c *ChainConfig) IsOnPlato(num *big.Int) bool { return configNumEqual(c.PlatoBlock, num) } +// IsHertz returns whether num is either equal to the block of enabling Berlin EIPs or greater. +func (c *ChainConfig) IsHertz(num *big.Int) bool { + return isForked(c.HertzBlock, num) +} + +// IsOnHertz returns whether num is equal to the fork block of enabling Berlin EIPs. +func (c *ChainConfig) IsOnHertz(num *big.Int) bool { + return configNumEqual(c.HertzBlock, num) +} + // IsMuirGlacier returns whether num is either equal to the Muir Glacier (EIP-2384) fork block or greater. func (c *ChainConfig) IsMuirGlacier(num *big.Int) bool { return isForked(c.MuirGlacierBlock, num) @@ -676,6 +695,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "gibbsBlock", block: c.GibbsBlock}, {name: "lubanBlock", block: c.LubanBlock}, {name: "platoBlock", block: c.PlatoBlock}, + {name: "hertzBlock", block: c.HertzBlock}, } { if lastFork.name != "" { // Next one must be higher number @@ -781,6 +801,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, head *big.Int) *Confi if isForkIncompatible(c.PlatoBlock, newcfg.PlatoBlock, head) { return newCompatError("plato fork block", c.PlatoBlock, newcfg.PlatoBlock) } + if isForkIncompatible(c.HertzBlock, newcfg.HertzBlock, head) { + return newCompatError("hertz fork block", c.HertzBlock, newcfg.HertzBlock) + } return nil } @@ -855,6 +878,7 @@ type Rules struct { IsPlanck bool IsLuban bool IsPlato bool + IsHertz bool } // Rules ensures c's ChainID is not nil. @@ -881,5 +905,6 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool) Rules { IsPlanck: c.IsPlanck(num), IsLuban: c.IsLuban(num), IsPlato: c.IsPlato(num), + IsHertz: c.IsHertz(num), } }