diff --git a/core/vm/eips.go b/core/vm/eips.go index 7c9f614463..772846f9fe 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -23,6 +23,8 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" ) @@ -718,8 +720,10 @@ func opExtCodeCopyEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC if overflow { uint64CodeOffset = math.MaxUint64 } - addr := common.Address(a.Bytes20()) - code := interpreter.evm.resolveCode(addr) + code := interpreter.evm.StateDB.GetCode(common.Address(a.Bytes20())) + if _, ok := types.ParseDelegation(code); ok { + code = types.DelegationPrefix[:2] + } codeCopy := getData(code, uint64CodeOffset, length.Uint64()) scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) @@ -729,18 +733,29 @@ func opExtCodeCopyEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeC // opExtCodeSizeEIP7702 implements the EIP-7702 variation of opExtCodeSize. func opExtCodeSizeEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() - slot.SetUint64(uint64(len(interpreter.evm.resolveCode(slot.Bytes20())))) + code := interpreter.evm.StateDB.GetCode(common.Address(slot.Bytes20())) + if _, ok := types.ParseDelegation(code); ok { + code = types.DelegationPrefix[:2] + } + slot.SetUint64(uint64(len(code))) return nil, nil } // opExtCodeHashEIP7702 implements the EIP-7702 variation of opExtCodeHash. func opExtCodeHashEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() - address := common.Address(slot.Bytes20()) - if interpreter.evm.StateDB.Empty(address) { + addr := common.Address(slot.Bytes20()) + if interpreter.evm.StateDB.Empty(addr) { slot.Clear() + return nil, nil + } + code := interpreter.evm.StateDB.GetCode(addr) + if _, ok := types.ParseDelegation(code); ok { + // If the code is a delegation, return the prefix without version. + slot.SetBytes(crypto.Keccak256(types.DelegationPrefix[:2])) } else { - slot.SetBytes(interpreter.evm.resolveCodeHash(address).Bytes()) + // Otherwise, return normal code hash. + slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(addr).Bytes()) } return nil, nil } diff --git a/core/vm/evm.go b/core/vm/evm.go index 31f3bbb36b..1a0215459c 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -583,7 +583,8 @@ func (evm *EVM) resolveCode(addr common.Address) []byte { // resolveCodeHash returns the code hash associated with the provided address. // After Prague, it can also resolve code hash of the account pointed to by a -// delegation designator. +// delegation designator. Although this is not accessible in the EVM it is used +// internally to associate jumpdest analysis to code. func (evm *EVM) resolveCodeHash(addr common.Address) common.Hash { if evm.chainRules.IsPrague { code := evm.StateDB.GetCode(addr)