Skip to content

Commit

Permalink
feat: trace EVM ops execution using Otel
Browse files Browse the repository at this point in the history
  • Loading branch information
youben11 committed Feb 12, 2024
1 parent a9d7b40 commit 2cbeca5
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 110 deletions.
9 changes: 1 addition & 8 deletions core/vm/contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
package vm

import (
"context"
"crypto/sha256"
"encoding/binary"
"errors"
Expand All @@ -33,7 +32,6 @@ import (
"github.com/ethereum/go-ethereum/crypto/kzg4844"
"github.com/ethereum/go-ethereum/params"
"github.com/zama-ai/fhevm-go/fhevm"
"go.opentelemetry.io/otel"
"golang.org/x/crypto/ripemd160"
)

Expand Down Expand Up @@ -201,12 +199,7 @@ func (c *fheLib) RequiredGas(accessibleState PrecompileAccessibleState, input []
}

func (c *fheLib) Run(accessibleState PrecompileAccessibleState, caller common.Address, addr common.Address, input []byte, readOnly bool) ([]byte, error) {
fmt.Println("CALL: func (c *fheLib) Run 3.0 --- conracts.go")
// tp := otel.GetTracerProvider()
ctx, span := otel.Tracer("fhevm").Start(context.TODO(), addr.String())
span.AddEvent("Calling precompile")
defer span.End()
return fhevm.FheLibRun(accessibleState.Interpreter().evm.FhevmEnvironment(), caller, addr, input, readOnly, ctx)
return fhevm.FheLibRun(accessibleState.Interpreter().evm.FhevmEnvironment(), caller, addr, input, readOnly)
}

// ECRECOVER implemented as a native contract.
Expand Down
12 changes: 9 additions & 3 deletions core/vm/evm.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
package vm

import (
"fmt"
"context"
"math/big"
"sync/atomic"

Expand Down Expand Up @@ -126,6 +126,9 @@ type EVM struct {
fhevmEnvironment FhevmImplementation
isGasEstimation bool
isEthCall bool
// Used by EVM ops to create Otel spans from a single context.
// The default value is nil and means we disable Otel
executionContext context.Context
}

type FhevmImplementation struct {
Expand Down Expand Up @@ -159,6 +162,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
fhevmEnvironment: FhevmImplementation{interpreter: nil, logger: &fhevm.DefaultLogger{}, data: fhevm.NewFhevmData(), params: fhevm.DefaultFhevmParams()},
isGasEstimation: config.IsGasEstimation,
isEthCall: config.IsEthCall,
executionContext: nil,
}
evm.interpreter = NewEVMInterpreter(evm)
evm.fhevmEnvironment.interpreter = evm.interpreter
Expand Down Expand Up @@ -194,8 +198,6 @@ func (evm *EVM) Interpreter() *EVMInterpreter {
// the necessary steps to create accounts and reverses the state in case of an
// execution error or failed value transfer.
func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas uint64, value *big.Int) (ret []byte, leftOverGas uint64, err error) {

fmt.Println("CALL: Call 1.0 --- evm.go")
// Fail if we're trying to execute above the call depth limit
if evm.depth > int(params.CallCreateDepth) {
return nil, gas, ErrDepth
Expand Down Expand Up @@ -607,3 +609,7 @@ func (evm *FhevmImplementation) CreateContract(caller common.Address, code []byt
func (evm *FhevmImplementation) CreateContract2(caller common.Address, code []byte, codeHash common.Hash, gas uint64, value *big.Int, address common.Address) ([]byte, common.Address, uint64, error) {
return evm.interpreter.evm.create(AccountRef(caller), &codeAndHash{code: code, hash: codeHash}, gas, value, address, CREATE2)
}

func (evm *FhevmImplementation) OtelContext() context.Context {
return evm.interpreter.evm.executionContext
}
9 changes: 0 additions & 9 deletions core/vm/instructions.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package vm

import (
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
Expand Down Expand Up @@ -516,14 +514,10 @@ func opMstore8(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
}

func opSload(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
fmt.Println("CALL: opSload 50.0 --- geth --- instructions.go")

return fhevm.OpSload(pc, interpreter.evm.FhevmEnvironment(), scope)
}

func opSstore(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
fmt.Println("CALL: opSstore 50.0 --- geth --- instructions.go")

return fhevm.OpSstore(pc, interpreter.evm.FhevmEnvironment(), scope)
}

Expand Down Expand Up @@ -619,7 +613,6 @@ func opCreate(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]b
}

func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
fmt.Println("CALL: opCreate2 5.0 --- instructions.go")
if interpreter.readOnly {
return nil, ErrWriteProtection
}
Expand Down Expand Up @@ -660,8 +653,6 @@ func opCreate2(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]
}

func opCall(pc *uint64, interpreter *EVMInterpreter, scope *ScopeContext) ([]byte, error) {
fmt.Println("CALL: opCall 4.0 --- instructions.go")

stack := scope.Stack
// Pop gas. The actual gas in interpreter.evm.callGasTemp.
// We can use this as a temporary value
Expand Down
83 changes: 8 additions & 75 deletions core/vm/interpreter.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,13 @@ package vm

import (
"context"
"encoding/binary"
"fmt"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/math"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/log"
"github.com/zama-ai/fhevm-go/fhevm"
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/trace"
)

// Config are the configuration options for the Interpreter
Expand Down Expand Up @@ -126,14 +123,18 @@ func NewEVMInterpreter(evm *EVM) *EVMInterpreter {
// considered a revert-and-consume-all-gas operation except for
// ErrExecutionReverted which means revert-and-keep-gas-left.
func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (ret []byte, err error) {
// Increment the call depth which is restricted to 1024
fmt.Println("CALL: Run 0.0 --- interpreter.go")
ctx, span := otel.Tracer("fhevm").Start(context.TODO(), "InterpreterRun")
// set the execution context to be used by ops
in.evm.executionContext = ctx
defer span.End()

// Increment the call depth which is restricted to 1024
in.evm.depth++
defer func() {
_, span := otel.Tracer("fhevm").Start(ctx, "RemoveVerifiedCipherextsAtCurrentDepth")
fhevm.RemoveVerifiedCipherextsAtCurrentDepth(in.evm.FhevmEnvironment())
span.End()

in.evm.depth--
}()

Expand Down Expand Up @@ -255,27 +256,7 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
logged = true
}
// execute the operation
// main span
var span trace.Span
if op.String() == STATICCALL.String() {

temp := callContext.Stack.pop()
// Pop other call parameters.
addr, inOffset, inSize, retOffset, retSize := callContext.Stack.pop(), callContext.Stack.pop(), callContext.Stack.pop(), callContext.Stack.pop(), callContext.Stack.pop()
callContext.Stack.push(&retSize)
callContext.Stack.push(&retOffset)
callContext.Stack.push(&inSize)
callContext.Stack.push(&inOffset)
callContext.Stack.push(&addr)
callContext.Stack.push(&temp)
var inputMemory = callContext.Memory.GetPtr(int64(inOffset.Uint64()), int64(inSize.Uint64()))
_, span = otel.Tracer("fhevm").Start(ctx, getFheFuncName(inputMemory))
}

res, err = operation.execute(&pc, in, callContext)
if op.String() == STATICCALL.String() {
span.End()
}

if err != nil {
break
Expand All @@ -284,58 +265,10 @@ func (in *EVMInterpreter) Run(contract *Contract, input []byte, readOnly bool) (
}

if err == errStopToken {
_, span := otel.Tracer("fhevm").Start(ctx, "EvalRemOptReqWhenStopToken")
err = fhevm.EvalRemOptReqWhenStopToken(in.evm.FhevmEnvironment())
span.End()
}

return res, err
}

func makeKeccakSignature(input string) uint32 {

return binary.BigEndian.Uint32(crypto.Keccak256([]byte(input))[0:4])
}

var signatureFheAdd = makeKeccakSignature("fheAdd(uint256,uint256,bytes1)")
var signatureFheLe = makeKeccakSignature("fheLe(uint256,uint256,bytes1)")
var signatureFheSub = makeKeccakSignature("fheSub(uint256,uint256,bytes1)")
var signatureFheIfThenElse = makeKeccakSignature("fheIfThenElse(uint256,uint256,uint256)")
var signatureVerifyCiphertext = makeKeccakSignature("verifyCiphertext(bytes)")
var signatureReencrypt = makeKeccakSignature("reencrypt(uint256,uint256)")
var signatureTrivialEncrypt = makeKeccakSignature("trivialEncrypt(uint256,bytes1)")
var signatureCast = makeKeccakSignature("cast(uint256,bytes1)")

func getFheFuncName(input []byte) string {
if len(input) < 4 {
return "tooShort"
}
// first 4 bytes are for the function signature
signature := binary.BigEndian.Uint32(input[0:4])
switch signature {
case signatureFheAdd:
return "fheAddRun"

case signatureFheSub:
return "fheSubRun"

case signatureFheLe:
return "fheLeRun"

case signatureFheIfThenElse:
return "fheIfThenElseRun"

case signatureVerifyCiphertext:
return "fheVerifyRun"

case signatureReencrypt:
return "fheReencryptRun"

case signatureTrivialEncrypt:
return "fheTrivialEncryptRun"

case signatureCast:
return "fheCastRun"

default:
return "fheUnknown"
}
}
11 changes: 4 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,10 @@ require (
github.com/tyler-smith/go-bip39 v1.1.0
github.com/urfave/cli/v2 v2.25.7
github.com/zama-ai/fhevm-go v0.1.5
go.opentelemetry.io/otel v1.23.0
go.opentelemetry.io/otel v1.23.1
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.23.0
go.opentelemetry.io/otel/sdk v1.23.0
go.opentelemetry.io/otel/trace v1.23.0
go.opentelemetry.io/otel/trace v1.23.1
go.uber.org/automaxprocs v1.5.2
golang.org/x/crypto v0.16.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
Expand Down Expand Up @@ -146,7 +146,7 @@ require (
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.0 // indirect
go.opentelemetry.io/otel/metric v1.23.0 // indirect
go.opentelemetry.io/otel/metric v1.23.1 // indirect
go.opentelemetry.io/proto/otlp v1.1.0 // indirect
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.19.0 // indirect
Expand All @@ -157,7 +157,4 @@ require (
rsc.io/tmplfunc v0.0.3 // indirect
)


replace (
github.com/zama-ai/fhevm-go v0.1.5 => ../fhevm-go
)
replace github.com/zama-ai/fhevm-go v0.1.5 => ../fhevm-go
14 changes: 6 additions & 8 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -489,20 +489,18 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zama-ai/fhevm-go v0.1.5 h1:In/36FLaKyzwLcX0MSKlE+DUSzC5HEvPH0nxQnDKtSM=
github.com/zama-ai/fhevm-go v0.1.5/go.mod h1:I9l8fujY69MEQhXnAnMLK2+rih3HI9JOS7TluLd+D2s=
go.opentelemetry.io/otel v1.23.0 h1:Df0pqjqExIywbMCMTxkAwzjLZtRf+bBKLbUcpxO2C9E=
go.opentelemetry.io/otel v1.23.0/go.mod h1:YCycw9ZeKhcJFrb34iVSkyT0iczq/zYDtZYFufObyB0=
go.opentelemetry.io/otel v1.23.1 h1:Za4UzOqJYS+MUczKI320AtqZHZb7EqxO00jAHE0jmQY=
go.opentelemetry.io/otel v1.23.1/go.mod h1:Td0134eafDLcTS4y+zQ26GE8u3dEuRBiBCTUIRHaikA=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.0 h1:D/cXD+03/UOphyyT87NX6h+DlU+BnplN6/P6KJwsgGc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.23.0/go.mod h1:L669qRGbPBwLcftXLFnTVFO6ES/GyMAvITLdvRjEAIM=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.23.0 h1:VZrBiTXzP3FErizsdF1JQj0qf0yA8Ktt6LAcjUhZqbc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.23.0/go.mod h1:xkkwo777b9MEfsyD1yUZa4g+7MCqqWAP3r2tTSZePRc=
go.opentelemetry.io/otel/metric v1.23.0 h1:pazkx7ss4LFVVYSxYew7L5I6qvLXHA0Ap2pwV+9Cnpo=
go.opentelemetry.io/otel/metric v1.23.0/go.mod h1:MqUW2X2a6Q8RN96E2/nqNoT+z9BSms20Jb7Bbp+HiTo=
go.opentelemetry.io/otel/metric v1.23.1 h1:PQJmqJ9u2QaJLBOELl1cxIdPcpbwzbkjfEyelTl2rlo=
go.opentelemetry.io/otel/metric v1.23.1/go.mod h1:mpG2QPlAfnK8yNhNJAxDZruU9Y1/HubbC+KyH8FaCWI=
go.opentelemetry.io/otel/sdk v1.23.0 h1:0KM9Zl2esnl+WSukEmlaAEjVY5HDZANOHferLq36BPc=
go.opentelemetry.io/otel/sdk v1.23.0/go.mod h1:wUscup7byToqyKJSilEtMf34FgdCAsFpFOjXnAwFfO0=
go.opentelemetry.io/otel/trace v1.23.0 h1:37Ik5Ib7xfYVb4V1UtnT97T1jI+AoIYkJyPkuL4iJgI=
go.opentelemetry.io/otel/trace v1.23.0/go.mod h1:GSGTbIClEsuZrGIzoEHqsVfxgn5UkggkflQwDScNUsk=
go.opentelemetry.io/otel/trace v1.23.1 h1:4LrmmEd8AU2rFvU1zegmvqW7+kWarxtNOPyeL6HmYY8=
go.opentelemetry.io/otel/trace v1.23.1/go.mod h1:4IpnpJFwr1mo/6HL8XIPJaE9y0+u1KcVmuW7dwFSVrI=
go.opentelemetry.io/proto/otlp v1.1.0 h1:2Di21piLrCqJ3U3eXGCTPHE9R8Nh+0uglSnOyxikMeI=
go.opentelemetry.io/proto/otlp v1.1.0/go.mod h1:GpBHCBWiqvVLDqmHZsoMM3C5ySeKTC7ej/RNTae6MdY=
go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME=
Expand Down

0 comments on commit 2cbeca5

Please sign in to comment.