diff --git a/common/constants.go b/common/constants.go index c923eeea8d..803443a781 100644 --- a/common/constants.go +++ b/common/constants.go @@ -49,6 +49,7 @@ var TIPXDCXDISABLE = big.NewInt(99999999900) var BerlinBlock = big.NewInt(9999999999) var LondonBlock = big.NewInt(9999999999) var MergeBlock = big.NewInt(9999999999) +var ShanghaiBlock = big.NewInt(9999999999) var TIPXDCXTestnet = big.NewInt(38383838) var IsTestnet bool = false diff --git a/common/constants/constants.go.devnet b/common/constants/constants.go.devnet index e80dda351f..2bbd3ac06a 100644 --- a/common/constants/constants.go.devnet +++ b/common/constants/constants.go.devnet @@ -49,6 +49,7 @@ var TIPXDCXDISABLE = big.NewInt(15894900) var BerlinBlock = big.NewInt(9999999999) var LondonBlock = big.NewInt(9999999999) var MergeBlock = big.NewInt(9999999999) +var ShanghaiBlock = big.NewInt(9999999999) var TIPXDCXTestnet = big.NewInt(0) var IsTestnet bool = false diff --git a/common/constants/constants.go.testnet b/common/constants/constants.go.testnet index 9a0125e701..3b2811ade9 100644 --- a/common/constants/constants.go.testnet +++ b/common/constants/constants.go.testnet @@ -49,6 +49,7 @@ var TIPXDCXDISABLE = big.NewInt(99999999900) var BerlinBlock = big.NewInt(9999999999) var LondonBlock = big.NewInt(9999999999) var MergeBlock = big.NewInt(9999999999) +var ShanghaiBlock = big.NewInt(9999999999) var TIPXDCXTestnet = big.NewInt(23779191) var IsTestnet bool = false diff --git a/core/vm/eips.go b/core/vm/eips.go index d096d5a3a8..48ffb0d691 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -29,6 +29,8 @@ import ( // defined jump tables are not polluted. func EnableEIP(eipNum int, jt *JumpTable) error { switch eipNum { + case 3855: + enable3855(jt) case 3198: enable3198(jt) case 2200: @@ -112,3 +114,20 @@ func opBaseFee(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([ callContext.stack.push(baseFee) return nil, nil } + +// enable3855 applies EIP-3855 (PUSH0 opcode) +func enable3855(jt *JumpTable) { + // New opcode + jt[PUSH0] = &operation{ + execute: opPush0, + constantGas: GasQuickStep, + minStack: minStack(0, 1), + maxStack: maxStack(0, 1), + } +} + +// opPush0 implements the PUSH0 opcode +func opPush0(pc *uint64, interpreter *EVMInterpreter, callContext *callCtx) ([]byte, error) { + callContext.stack.push(new(uint256.Int)) + return nil, nil +} diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index 29fc4a2cb7..23cc5a03fe 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -93,6 +93,8 @@ func NewEVMInterpreter(evm *EVM, cfg Config) *EVMInterpreter { // If jump table was not initialised we set the default one. if cfg.JumpTable == nil { switch { + case evm.chainRules.IsShanghai: + cfg.JumpTable = &shanghaiInstructionSet case evm.chainRules.IsMerge: cfg.JumpTable = &mergeInstructionSet case evm.chainRules.IsLondon: diff --git a/core/vm/jump_table.go b/core/vm/jump_table.go index 298ec63ab3..2302a439df 100644 --- a/core/vm/jump_table.go +++ b/core/vm/jump_table.go @@ -53,11 +53,18 @@ var ( berlinInstructionSet = newBerlinInstructionSet() londonInstructionSet = newLondonInstructionSet() mergeInstructionSet = newMergeInstructionSet() + shanghaiInstructionSet = newShanghaiInstructionSet() ) // JumpTable contains the EVM opcodes supported at a given fork. type JumpTable [256]*operation +func newShanghaiInstructionSet() JumpTable { + instructionSet := newMergeInstructionSet() + enable3855(&instructionSet) // PUSH0 instruction + return instructionSet +} + func newMergeInstructionSet() JumpTable { instructionSet := newLondonInstructionSet() instructionSet[PREVRANDAO] = &operation{ diff --git a/core/vm/opcodes.go b/core/vm/opcodes.go index 3b123f3a49..969354cf59 100644 --- a/core/vm/opcodes.go +++ b/core/vm/opcodes.go @@ -108,18 +108,19 @@ const ( // 0x50 range - 'storage' and execution. const ( - POP OpCode = 0x50 + iota - MLOAD - MSTORE - MSTORE8 - SLOAD - SSTORE - JUMP - JUMPI - PC - MSIZE - GAS - JUMPDEST + POP OpCode = 0x50 + MLOAD OpCode = 0x51 + MSTORE OpCode = 0x52 + MSTORE8 OpCode = 0x53 + SLOAD OpCode = 0x54 + SSTORE OpCode = 0x55 + JUMP OpCode = 0x56 + JUMPI OpCode = 0x57 + PC OpCode = 0x58 + MSIZE OpCode = 0x59 + GAS OpCode = 0x5a + JUMPDEST OpCode = 0x5b + PUSH0 OpCode = 0x5f ) // 0x60 range - pushes. @@ -300,6 +301,7 @@ var opCodeToString = [256]string{ MSIZE: "MSIZE", GAS: "GAS", JUMPDEST: "JUMPDEST", + PUSH0: "PUSH0", // 0x60 range - push. PUSH1: "PUSH1", @@ -462,6 +464,7 @@ var stringToOp = map[string]OpCode{ "MSIZE": MSIZE, "GAS": GAS, "JUMPDEST": JUMPDEST, + "PUSH0": PUSH0, "PUSH1": PUSH1, "PUSH2": PUSH2, "PUSH3": PUSH3, diff --git a/params/config.go b/params/config.go index 0a46f710f3..933d5f2980 100644 --- a/params/config.go +++ b/params/config.go @@ -498,7 +498,7 @@ func (c *ChainConfig) String() string { default: engine = "unknown" } - return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Istanbul: %v BerlinBlock: %v LondonBlock: %v MergeBlock: %v Engine: %v}", + return fmt.Sprintf("{ChainID: %v Homestead: %v DAO: %v DAOSupport: %v EIP150: %v EIP155: %v EIP158: %v Byzantium: %v Constantinople: %v Istanbul: %v BerlinBlock: %v LondonBlock: %v MergeBlock: %v ShanghaiBlock: %v Engine: %v}", c.ChainId, c.HomesteadBlock, c.DAOForkBlock, @@ -512,6 +512,7 @@ func (c *ChainConfig) String() string { common.BerlinBlock, common.LondonBlock, common.MergeBlock, + common.ShanghaiBlock, engine, ) } @@ -574,6 +575,11 @@ func (c *ChainConfig) IsMerge(num *big.Int) bool { return isForked(common.MergeBlock, num) } +// IsShanghai returns whether num is either equal to the Shanghai fork block or greater. +func (c *ChainConfig) IsShanghai(num *big.Int) bool { + return isForked(common.ShanghaiBlock, num) +} + func (c *ChainConfig) IsTIP2019(num *big.Int) bool { return isForked(common.TIP2019Block, num) } @@ -742,7 +748,7 @@ type Rules struct { IsHomestead, IsEIP150, IsEIP155, IsEIP158 bool IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool - IsMerge bool + IsMerge, IsShanghai bool } func (c *ChainConfig) Rules(num *big.Int) Rules { @@ -763,5 +769,6 @@ func (c *ChainConfig) Rules(num *big.Int) Rules { IsBerlin: c.IsBerlin(num), IsLondon: c.IsLondon(num), IsMerge: c.IsMerge(num), + IsShanghai: c.IsShanghai(num), } }