Skip to content
This repository has been archived by the owner on Dec 23, 2024. It is now read-only.

Commit

Permalink
feat: add clean interpreter.Run integration function
Browse files Browse the repository at this point in the history
  • Loading branch information
youben11 committed Dec 6, 2023
1 parent b32ca7a commit c1d7b32
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 24 deletions.
20 changes: 5 additions & 15 deletions fhevm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3153,16 +3153,6 @@ func TestFheRandEthCall(t *testing.T) {
}
}

func interpreterRunWithStopContract(environment *MockEVMEnvironment, interpreter *vm.EVMInterpreter, contract *vm.Contract, input []byte, readOnly bool) (ret []byte, err error) {
ret, _ = interpreter.Run(contract, input, readOnly)
// the following functions are meant to be ran from within interpreter.run so we increment depth to emulate that
environment.depth++
RemoveVerifiedCipherextsAtCurrentDepth(environment)
err = EvalRemOptReqWhenStopToken(environment)
environment.depth--
return ret, err
}

func newInterpreterFromEnvironment(environment *MockEVMEnvironment) *vm.EVMInterpreter {
cfg := vm.Config{}
evm := &vm.EVM{Config: cfg}
Expand Down Expand Up @@ -3206,7 +3196,7 @@ func TestLibOneTrueOptimisticRequire(t *testing.T) {

interpreter := newInterpreterFromEnvironment(environment)
// Call the interpreter with a single STOP opcode and expect that the optimistic require doesn't revert.
out, err = interpreterRunWithStopContract(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
out, err = InterpreterRun(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
if err != nil {
t.Fatalf(err.Error())
} else if out != nil {
Expand All @@ -3230,7 +3220,7 @@ func TestOneFalseOptimisticRequire(t *testing.T) {
}
interpreter := newInterpreterFromEnvironment(environment)
// Call the interpreter with a single STOP opcode and expect that the optimistic require reverts.
out, err = interpreterRunWithStopContract(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
out, err = InterpreterRun(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
if err == nil || err != ErrExecutionReverted {
t.Fatalf("require expected reversal on value 0")
} else if out != nil {
Expand Down Expand Up @@ -3261,7 +3251,7 @@ func TestTwoTrueOptimisticRequires(t *testing.T) {
}
interpreter := newInterpreterFromEnvironment(environment)
// Call the interpreter with a single STOP opcode and expect that the optimistic require doesn't revert.
out, err = interpreterRunWithStopContract(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
out, err = InterpreterRun(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
if err != nil {
t.Fatalf(err.Error())
} else if out != nil {
Expand Down Expand Up @@ -3292,7 +3282,7 @@ func TestOptimisticRequireTwiceOnSameCiphertext(t *testing.T) {
}
interpreter := newInterpreterFromEnvironment(environment)
// Call the interpreter with a single STOP opcode and expect that the optimistic require doesn't revert.
out, err = interpreterRunWithStopContract(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
out, err = InterpreterRun(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
if err != nil {
t.Fatalf(err.Error())
} else if out != nil {
Expand Down Expand Up @@ -3322,7 +3312,7 @@ func TestOneFalseAndOneTrueOptimisticRequire(t *testing.T) {
}
interpreter := newInterpreterFromEnvironment(environment)
// Call the interpreter with a single STOP opcode and expect that the optimistic require reverts.
out, err = interpreterRunWithStopContract(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
out, err = InterpreterRun(environment, interpreter, newStopOpcodeContract(), make([]byte, 0), readOnly)
if err == nil || err != ErrExecutionReverted {
t.Fatalf("require expected reversal on value 0")
} else if out != nil {
Expand Down
6 changes: 3 additions & 3 deletions fhevm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,15 +335,15 @@ func delegateCiphertextHandlesToCaller(env EVMEnvironment, ret []byte) {
}
}

func RemoveVerifiedCipherextsAtCurrentDepth(env EVMEnvironment) {
func RemoveVerifiedCipherextsAtCurrentDepth(env EVMEnvironment, depth int) {
for _, verifiedCiphertext := range env.FhevmData().verifiedCiphertexts {
if env.IsCommitting() {
env.GetLogger().Info("Run removing ciphertext from depth",
"handle", verifiedCiphertext.ciphertext.getHash().Hex(),
"depth", env.GetDepth())
"depth", depth)
}
// Delete the current EVM depth from the set of verified depths.
verifiedCiphertext.verifiedDepths.del(env.GetDepth())
verifiedCiphertext.verifiedDepths.del(depth)
}
}

Expand Down
28 changes: 22 additions & 6 deletions fhevm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fhevm

import (
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)

type ScopeContext interface {
Expand Down Expand Up @@ -67,17 +68,32 @@ var PrivilegedMempory *PrivilegedMemory = &PrivilegedMemory{
//
// This function is meant to be integrated as part of vm.EVMInterpreter.Run in the case
// there was an errStopToken
func EvalRemOptReqWhenStopToken(env EVMEnvironment) (err error) {
err = nil
func EvalRemOptReqWhenStopToken(env EVMEnvironment, depth int) (err error) {
// If we are finishing execution (about to go to from depth 1 to depth 0), evaluate
// any remaining optimistic requires.
if env.GetDepth() == 1 {
if depth == 1 {
result, evalErr := evaluateRemainingOptimisticRequires(env)
if evalErr != nil {
err = evalErr
return evalErr
} else if !result {
err = ErrExecutionReverted
return ErrExecutionReverted
}
}
return err
return nil
}

// Function meant to be run instead of vm.EVMInterpreter.Run inside an fhEVM
//
// It makes sure to remove ciphertexts used at current depth during interpreter execution, but also evaluate remaining optimistic requires if necessary
func InterpreterRun(environment EVMEnvironment, interpreter *vm.EVMInterpreter, contract *vm.Contract, input []byte, readOnly bool) (ret []byte, err error) {
ret, err = interpreter.Run(contract, input, readOnly)
// the following functions are meant to be ran from within interpreter.Run so we increment depth to emulate that
depth := environment.GetDepth() + 1
RemoveVerifiedCipherextsAtCurrentDepth(environment, depth)
// if contract is not empty and err is nil, then an errStopToken was cleared inside interpreter.Run
if len(contract.Code) != 0 && err == nil {
err = EvalRemOptReqWhenStopToken(environment, depth)
return ret, err
}
return ret, err
}

0 comments on commit c1d7b32

Please sign in to comment.