From db1459d46638b9a0e5a121cb56e90b5dfcba1198 Mon Sep 17 00:00:00 2001 From: lightclient Date: Thu, 21 Nov 2024 12:47:36 +0800 Subject: [PATCH] core/vm: make 7702 variants of EXT* ops --- core/vm/eips.go | 43 +++++++++++++++++++++++++++++++++++++++++ core/vm/instructions.go | 11 ++++------- 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/core/vm/eips.go b/core/vm/eips.go index b8024bc590..db297ce46b 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -705,14 +705,57 @@ func enableEOF(jt *JumpTable) { } } +// opExtCodeCopyEIP7702 implements the EIP-7702 variation of opExtCodeCopy. +func opExtCodeCopyEIP7702(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { + var ( + stack = scope.Stack + a = stack.pop() + memOffset = stack.pop() + codeOffset = stack.pop() + length = stack.pop() + ) + uint64CodeOffset, overflow := codeOffset.Uint64WithOverflow() + if overflow { + uint64CodeOffset = math.MaxUint64 + } + addr := common.Address(a.Bytes20()) + code := interpreter.evm.StateDB.ResolveCode(addr) + codeCopy := getData(code, uint64CodeOffset, length.Uint64()) + scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) + + return nil, nil +} + +// 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.StateDB.ResolveCode(slot.Bytes20())))) + 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) { + slot.Clear() + } else { + slot.SetBytes(interpreter.evm.StateDB.ResolveCodeHash(address).Bytes()) + } + return nil, nil +} + // enable7702 the EIP-7702 changes to support delegation designators. func enable7702(jt *JumpTable) { + jt[EXTCODECOPY].execute = opExtCodeCopyEIP7702 jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929 jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP7702 + jt[EXTCODESIZE].execute = opExtCodeSizeEIP7702 jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929 jt[EXTCODESIZE].dynamicGas = gasEip7702CodeCheck + jt[EXTCODEHASH].execute = opExtCodeHashEIP7702 jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929 jt[EXTCODEHASH].dynamicGas = gasEip7702CodeCheck diff --git a/core/vm/instructions.go b/core/vm/instructions.go index 954d09b4f0..47eb62be08 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -340,7 +340,7 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) { slot := scope.Stack.peek() - slot.SetUint64(uint64(len(interpreter.evm.StateDB.ResolveCode(slot.Bytes20())))) + slot.SetUint64(uint64(interpreter.evm.StateDB.GetCodeSize(slot.Bytes20()))) return nil, nil } @@ -378,7 +378,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) uint64CodeOffset = math.MaxUint64 } addr := common.Address(a.Bytes20()) - code := interpreter.evm.StateDB.ResolveCode(addr) + code := interpreter.evm.StateDB.GetCode(addr) codeCopy := getData(code, uint64CodeOffset, length.Uint64()) scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy) @@ -387,7 +387,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // opExtCodeHash returns the code hash of a specified account. // There are several cases when the function is called, while we can relay everything -// to `state.ResolveCodeHash` function to ensure the correctness. +// to `state.GetCodeHash` function to ensure the correctness. // // 1. Caller tries to get the code hash of a normal contract account, state // should return the relative code hash and set it as the result. @@ -401,9 +401,6 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) // 4. Caller tries to get the code hash of a precompiled account, the result should be // zero or emptyCodeHash. // -// 4. Caller tries to get the code hash of a delegated account, the result should be -// equal the result of calling extcodehash on the account directly. -// // It is worth noting that in order to avoid unnecessary create and clean, all precompile // accounts on mainnet have been transferred 1 wei, so the return here should be // emptyCodeHash. If the precompile account is not transferred any amount on a private or @@ -420,7 +417,7 @@ func opExtCodeHash(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) if interpreter.evm.StateDB.Empty(address) { slot.Clear() } else { - slot.SetBytes(interpreter.evm.StateDB.ResolveCodeHash(address).Bytes()) + slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes()) } return nil, nil }