Skip to content

Commit

Permalink
core/vm: make 7702 variants of EXT* ops
Browse files Browse the repository at this point in the history
  • Loading branch information
lightclient committed Dec 12, 2024
1 parent a173914 commit 7dceb35
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 7 deletions.
43 changes: 43 additions & 0 deletions core/vm/eips.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
11 changes: 4 additions & 7 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down Expand Up @@ -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)

Expand All @@ -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.
Expand All @@ -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
Expand All @@ -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
}
Expand Down

0 comments on commit 7dceb35

Please sign in to comment.