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

Commit

Permalink
refactor: remove optReq
Browse files Browse the repository at this point in the history
  • Loading branch information
immortal-tofu committed Mar 8, 2024
1 parent dea7141 commit 52ce1a6
Show file tree
Hide file tree
Showing 7 changed files with 0 additions and 395 deletions.
242 changes: 0 additions & 242 deletions fhevm/contracts_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,26 +77,6 @@ func toPrecompileInputNoScalar(isScalar bool, hashes ...common.Hash) []byte {
return ret
}

func evaluateRemainingOptimisticRequiresWithoutKms(environment EVMEnvironment) (bool, error) {
requires := environment.FhevmData().optimisticRequires
len := len(requires)
defer func() { environment.FhevmData().resetOptimisticRequires() }()
if len != 0 {
var cumulative *tfhe.TfheCiphertext = requires[0]
var err error
for i := 1; i < len; i++ {
cumulative, err = cumulative.Bitand(requires[i])
if err != nil {
environment.GetLogger().Error("evaluateRemainingOptimisticRequires bitand failed", "err", err)
return false, err
}
}
result, err := cumulative.Decrypt()
return result.Uint64() != 0, err
}
return true, nil
}

func decryptRunWithoutKms(environment EVMEnvironment, caller common.Address, addr common.Address, input []byte, readOnly bool) ([]byte, error) {
logger := environment.GetLogger()
// if not gas estimation and not view function fail if decryptions are disabled in transactions
Expand All @@ -122,13 +102,6 @@ func decryptRunWithoutKms(environment EVMEnvironment, caller common.Address, add
if !environment.IsCommitting() && !environment.IsEthCall() {
return bytes.Repeat([]byte{0xFF}, 32), nil
}
// Make sure we don't decrypt before any optimistic requires are checked.
optReqResult, optReqErr := evaluateRemainingOptimisticRequiresWithoutKms(environment)
if optReqErr != nil {
return nil, optReqErr
} else if !optReqResult {
return nil, ErrExecutionReverted
}

plaintext, err := ct.ciphertext.Decrypt()
if err != nil {
Expand Down Expand Up @@ -4170,27 +4143,11 @@ func TestFheRandBoundedEthCall(t *testing.T) {
}
}

func EvalRemOptReqWhenStopTokenWithoutKms(env EVMEnvironment) (err error) {
err = nil
// If we are finishing execution (about to go to from depth 1 to depth 0), evaluate
// any remaining optimistic requires.
if env.GetDepth() == 1 {
result, evalErr := evaluateRemainingOptimisticRequiresWithoutKms(env)
if evalErr != nil {
err = evalErr
} else if !result {
err = ErrExecutionReverted
}
}
return err
}

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 = EvalRemOptReqWhenStopTokenWithoutKms(environment)
environment.depth--
return ret, err
}
Expand All @@ -4215,205 +4172,6 @@ func newStopOpcodeContract() *vm.Contract {
return c
}

func TestLibOneTrueOptimisticRequire(t *testing.T) {
var value uint64 = 1
signature := "optimisticRequire(uint256)"
hashRes := crypto.Keccak256([]byte(signature))
signatureBytes := hashRes[0:4]
depth := 1
environment := newTestEVMEnvironment()
environment.depth = depth
addr := common.Address{}
readOnly := false
input := make([]byte, 0)
hash := verifyCiphertextInTestMemory(environment, value, depth, tfhe.FheUint8).GetHash()
input = append(input, signatureBytes...)
input = append(input, hash.Bytes()...)
out, err := FheLibRun(environment, addr, addr, input, readOnly)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}

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)
if err != nil {
t.Fatalf(err.Error())
} else if out != nil {
t.Fatalf("expected empty response")
}
}

func TestOneFalseOptimisticRequire(t *testing.T) {
var value uint64 = 0
depth := 0
environment := newTestEVMEnvironment()
environment.depth = depth
addr := common.Address{}
readOnly := false
hash := verifyCiphertextInTestMemory(environment, value, depth, tfhe.FheUint8).GetHash()
out, err := optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
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)
if err == nil || err != ErrExecutionReverted {
t.Fatalf("require expected reversal on value 0")
} else if out != nil {
t.Fatalf("expected empty response")
}
}

func TestTwoTrueOptimisticRequires(t *testing.T) {
var value uint64 = 1
depth := 1
environment := newTestEVMEnvironment()
environment.depth = depth
addr := common.Address{}
readOnly := false
hash := verifyCiphertextInTestMemory(environment, value, depth, tfhe.FheUint8).GetHash()
out, err := optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
hash = verifyCiphertextInTestMemory(environment, value, depth, tfhe.FheUint8).GetHash()
out, err = optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
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)
if err != nil {
t.Fatalf(err.Error())
} else if out != nil {
t.Fatalf("expected empty response")
}
}

func TestOptimisticRequireTwiceOnSameCiphertext(t *testing.T) {
var value uint64 = 1
depth := 1
environment := newTestEVMEnvironment()
environment.depth = depth
addr := common.Address{}
readOnly := false
ct := verifyCiphertextInTestMemory(environment, value, depth, tfhe.FheUint8)
hash := ct.GetHash()
out, err := optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
out, err = optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
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)
if err != nil {
t.Fatalf(err.Error())
} else if out != nil {
t.Fatalf("expected empty response")
}
}

func TestOneFalseAndOneTrueOptimisticRequire(t *testing.T) {
depth := 0
environment := newTestEVMEnvironment()
environment.depth = depth
addr := common.Address{}
readOnly := false
hash := verifyCiphertextInTestMemory(environment, 0, depth, tfhe.FheUint8).GetHash()
out, err := optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
hash = verifyCiphertextInTestMemory(environment, 1, depth, tfhe.FheUint8).GetHash()
out, err = optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
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)
if err == nil || err != ErrExecutionReverted {
t.Fatalf("require expected reversal on value 0")
} else if out != nil {
t.Fatalf("expected empty response")
}
}

func TestDecryptWithFalseOptimisticRequire(t *testing.T) {
depth := 0
environment := newTestEVMEnvironment()
environment.depth = depth
addr := common.Address{}
readOnly := false
// Call optimistic require with a false value and expect it succeeds.
hash := verifyCiphertextInTestMemory(environment, 0, depth, tfhe.FheUint8).GetHash()
out, err := optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
// Call decrypt and expect it to fail due to the optimistic require being false.
_, err = decryptRunWithoutKms(environment, addr, addr, hash.Bytes(), readOnly)
if err == nil {
t.Fatalf("expected decrypt fails due to false optimistic require")
}
// Make sure there are no more optimistic requires after the decrypt call.
if len(environment.FhevmData().optimisticRequires) != 0 {
t.Fatalf("expected that there are no optimistic requires after decrypt")
}
}

func TestDecryptWithTrueOptimisticRequire(t *testing.T) {
depth := 0
environment := newTestEVMEnvironment()
environment.depth = depth
addr := common.Address{}
readOnly := false
// Call optimistic require with a false value and expect it succeeds.
hash := verifyCiphertextInTestMemory(environment, 1, depth, tfhe.FheUint8).GetHash()
out, err := optimisticRequireRun(environment, addr, addr, hash.Bytes(), readOnly, nil)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 0 {
t.Fatalf("require expected output len of 0, got %v", len(out))
}
// Call decrypt and expect it to succeed due to the optimistic require being true.
out, err = decryptRunWithoutKms(environment, addr, addr, hash.Bytes(), readOnly)
if err != nil {
t.Fatalf(err.Error())
} else if len(out) != 32 {
t.Fatalf("decrypt expected output len of 32, got %v", len(out))
}
// Make sure there are no more optimistic requires after the decrypt call.
if len(environment.FhevmData().optimisticRequires) != 0 {
t.Fatalf("expected that there are no optimistic requires after decrypt")
}
}

func TestDecryptInTransactionDisabled(t *testing.T) {
depth := 0
environment := newTestEVMEnvironment()
Expand Down
6 changes: 0 additions & 6 deletions fhevm/fhelib.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,12 +226,6 @@ var fhelibMethods = []*FheLibMethod{
requiredGasFunction: verifyCiphertextRequiredGas,
runFunction: verifyCiphertextRun,
},
{
name: "optimisticRequire",
argTypes: "(uint256)",
requiredGasFunction: optimisticRequireRequiredGas,
runFunction: optimisticRequireRun,
},
{
name: "getCiphertext",
argTypes: "(address,uint256)",
Expand Down
15 changes: 0 additions & 15 deletions fhevm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

"github.com/ethereum/go-ethereum/common"
"github.com/holiman/uint256"
"github.com/zama-ai/fhevm-go/fhevm/tfhe"
)

type EVMEnvironment interface {
Expand Down Expand Up @@ -47,25 +46,11 @@ type FhevmData struct {
// A map from a ciphertext hash to itself and stack depth at which it is verified
verifiedCiphertexts map[common.Hash]*verifiedCiphertext

// All optimistic requires encountered up to that point in the txn execution
optimisticRequires []*tfhe.TfheCiphertext

nextCiphertextHashOnGasEst uint256.Int
}

// Set the optimisticRequires array to an empty array
func (data *FhevmData) resetOptimisticRequires() {
data.optimisticRequires = make([]*tfhe.TfheCiphertext, 0)
}

// Append one ciphertext to the optimisticRequires array
func (data *FhevmData) appendOptimisticRequires(ct *tfhe.TfheCiphertext) {
data.optimisticRequires = append(data.optimisticRequires, ct)
}

func NewFhevmData() FhevmData {
return FhevmData{
verifiedCiphertexts: make(map[common.Hash]*verifiedCiphertext),
optimisticRequires: make([]*tfhe.TfheCiphertext, 0),
}
}
22 changes: 0 additions & 22 deletions fhevm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,9 @@ func (vc *verifiedCiphertext) hash() common.Hash {
type PrivilegedMemory struct {
// A map from a ciphertext hash to itself and stack depths at which it is verified
VerifiedCiphertexts map[common.Hash]*verifiedCiphertext

// All optimistic requires encountered up to that point in the txn execution
optimisticRequires []*tfhe.TfheCiphertext
}

var PrivilegedMempory *PrivilegedMemory = &PrivilegedMemory{
make(map[common.Hash]*verifiedCiphertext),
make([]*tfhe.TfheCiphertext, 0),
}

// Evaluate remaining optimistic requires when Interpreter.Run get an errStopToken
//
// 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
// If we are finishing execution (about to go to from depth 1 to depth 0), evaluate
// any remaining optimistic requires.
if env.GetDepth() == 1 {
result, evalErr := evaluateRemainingOptimisticRequires(env)
if evalErr != nil {
err = evalErr
} else if !result {
err = ErrExecutionReverted
}
}
return err
}
Loading

0 comments on commit 52ce1a6

Please sign in to comment.