mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 18:02:24 +00:00
core/vm: make 7702 variants of EXT* ops
This commit is contained in:
parent
a173914225
commit
7dceb35670
2 changed files with 47 additions and 7 deletions
|
|
@ -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.
|
// enable7702 the EIP-7702 changes to support delegation designators.
|
||||||
func enable7702(jt *JumpTable) {
|
func enable7702(jt *JumpTable) {
|
||||||
|
jt[EXTCODECOPY].execute = opExtCodeCopyEIP7702
|
||||||
jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929
|
jt[EXTCODECOPY].constantGas = params.WarmStorageReadCostEIP2929
|
||||||
jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP7702
|
jt[EXTCODECOPY].dynamicGas = gasExtCodeCopyEIP7702
|
||||||
|
|
||||||
|
jt[EXTCODESIZE].execute = opExtCodeSizeEIP7702
|
||||||
jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929
|
jt[EXTCODESIZE].constantGas = params.WarmStorageReadCostEIP2929
|
||||||
jt[EXTCODESIZE].dynamicGas = gasEip7702CodeCheck
|
jt[EXTCODESIZE].dynamicGas = gasEip7702CodeCheck
|
||||||
|
|
||||||
|
jt[EXTCODEHASH].execute = opExtCodeHashEIP7702
|
||||||
jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929
|
jt[EXTCODEHASH].constantGas = params.WarmStorageReadCostEIP2929
|
||||||
jt[EXTCODEHASH].dynamicGas = gasEip7702CodeCheck
|
jt[EXTCODEHASH].dynamicGas = gasEip7702CodeCheck
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -340,7 +340,7 @@ func opReturnDataCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeConte
|
||||||
|
|
||||||
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
func opExtCodeSize(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
|
||||||
slot := scope.Stack.peek()
|
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
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,7 +378,7 @@ func opExtCodeCopy(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext)
|
||||||
uint64CodeOffset = math.MaxUint64
|
uint64CodeOffset = math.MaxUint64
|
||||||
}
|
}
|
||||||
addr := common.Address(a.Bytes20())
|
addr := common.Address(a.Bytes20())
|
||||||
code := interpreter.evm.StateDB.ResolveCode(addr)
|
code := interpreter.evm.StateDB.GetCode(addr)
|
||||||
codeCopy := getData(code, uint64CodeOffset, length.Uint64())
|
codeCopy := getData(code, uint64CodeOffset, length.Uint64())
|
||||||
scope.Memory.Set(memOffset.Uint64(), length.Uint64(), codeCopy)
|
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.
|
// opExtCodeHash returns the code hash of a specified account.
|
||||||
// There are several cases when the function is called, while we can relay everything
|
// 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
|
// 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.
|
// 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
|
// 4. Caller tries to get the code hash of a precompiled account, the result should be
|
||||||
// zero or emptyCodeHash.
|
// 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
|
// 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
|
// 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
|
// 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) {
|
if interpreter.evm.StateDB.Empty(address) {
|
||||||
slot.Clear()
|
slot.Clear()
|
||||||
} else {
|
} else {
|
||||||
slot.SetBytes(interpreter.evm.StateDB.ResolveCodeHash(address).Bytes())
|
slot.SetBytes(interpreter.evm.StateDB.GetCodeHash(address).Bytes())
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue