Skip to content

Commit

Permalink
fix: format error trace for rpc v0.8
Browse files Browse the repository at this point in the history
  • Loading branch information
AnkushinDaniil committed Feb 26, 2025
1 parent d4fffa4 commit 459542c
Show file tree
Hide file tree
Showing 29 changed files with 517 additions and 261 deletions.
16 changes: 8 additions & 8 deletions mocks/mock_vm.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions node/throttled_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,24 @@ func NewThrottledVM(res vm.VM, concurrenyBudget uint, maxQueueLen int32) *Thrott
}

func (tvm *ThrottledVM) Call(callInfo *vm.CallInfo, blockInfo *vm.BlockInfo, state core.StateReader,
network *utils.Network, maxSteps uint64, sierraVersion string,
network *utils.Network, maxSteps uint64, sierraVersion string, errStack bool,
) (vm.CallResult, error) {
ret := vm.CallResult{}
return ret, tvm.Do(func(vm *vm.VM) error {
var err error
ret, err = (*vm).Call(callInfo, blockInfo, state, network, maxSteps, sierraVersion)
ret, err = (*vm).Call(callInfo, blockInfo, state, network, maxSteps, sierraVersion, errStack)

Check warning on line 28 in node/throttled_vm.go

View check run for this annotation

Codecov / codecov/patch

node/throttled_vm.go#L28

Added line #L28 was not covered by tests
return err
})
}

func (tvm *ThrottledVM) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt,
blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool,
blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert, errStack bool,
) (vm.ExecutionResults, error) {
var executionResult vm.ExecutionResults
return executionResult, tvm.Do(func(vm *vm.VM) error {
var err error
executionResult, err = (*vm).Execute(txns, declaredClasses, paidFeesOnL1, blockInfo, state, network,
skipChargeFee, skipValidate, errOnRevert)
skipChargeFee, skipValidate, errOnRevert, errStack)

Check warning on line 40 in node/throttled_vm.go

View check run for this annotation

Codecov / codecov/patch

node/throttled_vm.go#L40

Added line #L40 was not covered by tests
return err
})
}
10 changes: 5 additions & 5 deletions rpc/v6/estimate_fee.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package rpcv6

import (
"errors"
"encoding/json"
"fmt"

"github.com/NethermindEth/juno/core/felt"
Expand Down Expand Up @@ -88,19 +88,19 @@ func (h *Handler) estimateMessageFee(msg MsgFromL1, id BlockID, f estimateFeeHan
if rpcErr != nil {
if rpcErr.Code == rpccore.ErrTransactionExecutionError.Code {
data := rpcErr.Data.(TransactionExecutionErrorData)
return nil, MakeContractError(errors.New(data.ExecutionError))
return nil, MakeContractError(data.ExecutionError)

Check warning on line 91 in rpc/v6/estimate_fee.go

View check run for this annotation

Codecov / codecov/patch

rpc/v6/estimate_fee.go#L91

Added line #L91 was not covered by tests
}
return nil, rpcErr
}
return &estimates[0], nil
}

type ContractErrorData struct {
RevertError string `json:"revert_error"`
RevertError json.RawMessage `json:"revert_error"`
}

func MakeContractError(err error) *jsonrpc.Error {
func MakeContractError(err json.RawMessage) *jsonrpc.Error {
return rpccore.ErrContractError.CloneWithData(ContractErrorData{
RevertError: err.Error(),
RevertError: err,
})
}
4 changes: 2 additions & 2 deletions rpc/v6/estimate_fee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ func TestEstimateMessageFee(t *testing.T) {
expectedGasConsumed := new(felt.Felt).SetUint64(37)
mockVM.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), &vm.BlockInfo{
Header: latestHeader,
}, gomock.Any(), &utils.Mainnet, gomock.Any(), false, true).DoAndReturn(
}, gomock.Any(), &utils.Mainnet, gomock.Any(), false, true, false).DoAndReturn(
func(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *vm.BlockInfo,
state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool,
state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert, errStack bool,
) (vm.ExecutionResults, error) {
require.Len(t, txns, 1)
assert.NotNil(t, txns[0].(*core.L1HandlerTransaction))
Expand Down
9 changes: 5 additions & 4 deletions rpc/v6/simulation.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package rpcv6

import (
"encoding/json"
"errors"
"fmt"
"slices"
Expand Down Expand Up @@ -101,7 +102,7 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra
BlockHashToBeRevealed: blockHashToBeRevealed,
}
executionResults, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo,
state, h.bcReader.Network(), skipFeeCharge, skipValidate, errOnRevert)
state, h.bcReader.Network(), skipFeeCharge, skipValidate, errOnRevert, false)
if err != nil {
if errors.Is(err, utils.ErrResourceBusy) {
return nil, rpccore.ErrInternal.CloneWithData(rpccore.ThrottledVMErr)
Expand Down Expand Up @@ -157,13 +158,13 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra
}

type TransactionExecutionErrorData struct {
TransactionIndex uint64 `json:"transaction_index"`
ExecutionError string `json:"execution_error"`
TransactionIndex uint64 `json:"transaction_index"`
ExecutionError json.RawMessage `json:"execution_error"`
}

func makeTransactionExecutionError(err *vm.TransactionExecutionError) *jsonrpc.Error {
return rpccore.ErrTransactionExecutionError.CloneWithData(TransactionExecutionErrorData{
TransactionIndex: err.Index,
ExecutionError: err.Cause.Error(),
ExecutionError: err.Cause,
})
}
18 changes: 9 additions & 9 deletions rpc/v6/simulation_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package rpcv6_test

import (
"errors"
"encoding/json"
"testing"

"github.com/NethermindEth/juno/core"
Expand Down Expand Up @@ -38,7 +38,7 @@ func TestSimulateTransactions(t *testing.T) {
stepsUsed := uint64(123)
mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{
Header: headsHeader,
}, mockState, n, true, false, false).
}, mockState, n, true, false, false, false).
Return(vm.ExecutionResults{
OverallFees: []*felt.Felt{},
DataAvailability: []core.DataAvailability{},
Expand All @@ -54,7 +54,7 @@ func TestSimulateTransactions(t *testing.T) {
stepsUsed := uint64(123)
mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{
Header: headsHeader,
}, mockState, n, false, true, false).
}, mockState, n, false, true, false, false).
Return(vm.ExecutionResults{
OverallFees: []*felt.Felt{},
DataAvailability: []core.DataAvailability{},
Expand All @@ -69,30 +69,30 @@ func TestSimulateTransactions(t *testing.T) {
t.Run("transaction execution error", func(t *testing.T) {
mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{
Header: headsHeader,
}, mockState, n, false, true, false).
}, mockState, n, false, true, false, false).
Return(vm.ExecutionResults{}, vm.TransactionExecutionError{
Index: 44,
Cause: errors.New("oops"),
Cause: json.RawMessage("oops"),
})

_, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag})
require.Equal(t, rpccore.ErrTransactionExecutionError.CloneWithData(rpc.TransactionExecutionErrorData{
TransactionIndex: 44,
ExecutionError: "oops",
ExecutionError: json.RawMessage("oops"),
}), err)

mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{
Header: headsHeader,
}, mockState, n, false, true, false).
}, mockState, n, false, true, false, false).
Return(vm.ExecutionResults{}, vm.TransactionExecutionError{
Index: 44,
Cause: errors.New("oops"),
Cause: json.RawMessage("oops"),
})

_, err = handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag})
require.Equal(t, rpccore.ErrTransactionExecutionError.CloneWithData(rpc.TransactionExecutionErrorData{
TransactionIndex: 44,
ExecutionError: "oops",
ExecutionError: json.RawMessage("oops"),
}), err)
})
}
9 changes: 5 additions & 4 deletions rpc/v6/trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package rpcv6

import (
"context"
"encoding/json"
"errors"
"net/http"
"slices"
Expand Down Expand Up @@ -256,7 +257,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block,
}

executionResults, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, &blockInfo, state, network, false,
false, false)
false, false, false)
if err != nil {
if errors.Is(err, utils.ErrResourceBusy) {
return nil, rpccore.ErrInternal.CloneWithData(rpccore.ThrottledVMErr)
Expand Down Expand Up @@ -379,15 +380,15 @@ func (h *Handler) call(funcCall FunctionCall, id BlockID) ([]*felt.Felt, *jsonrp
}, &vm.BlockInfo{
Header: header,
BlockHashToBeRevealed: blockHashToBeRevealed,
}, state, h.bcReader.Network(), h.callMaxSteps, "")
}, state, h.bcReader.Network(), h.callMaxSteps, "", false)
if err != nil {
if errors.Is(err, utils.ErrResourceBusy) {
return nil, rpccore.ErrInternal.CloneWithData(rpccore.ThrottledVMErr)
}
return nil, MakeContractError(err)
return nil, MakeContractError(json.RawMessage(err.Error()))

Check warning on line 388 in rpc/v6/trace.go

View check run for this annotation

Codecov / codecov/patch

rpc/v6/trace.go#L388

Added line #L388 was not covered by tests
}
if res.ExecutionFailed {
return nil, MakeContractError(errors.New(utils.FeltArrToString(res.Result)))
return nil, MakeContractError(json.RawMessage(utils.FeltArrToString(res.Result)))
}
return res.Result, nil
}
14 changes: 7 additions & 7 deletions rpc/v6/trace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ func TestTraceTransactionV0_6(t *testing.T) {
vmTrace := new(vm.TransactionTrace)
require.NoError(t, json.Unmarshal(vmTraceJSON, vmTrace))
mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{},
&vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false).
&vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false, false).
Return(vm.ExecutionResults{
DataAvailability: []core.DataAvailability{{L1DataGas: 0}},
Traces: []vm.TransactionTrace{*vmTrace},
Expand Down Expand Up @@ -199,7 +199,7 @@ func TestTraceTransactionV0_6(t *testing.T) {
vmTrace := new(vm.TransactionTrace)
require.NoError(t, json.Unmarshal(vmTraceJSON, vmTrace))
mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{},
&vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false).
&vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false, false).
Return(vm.ExecutionResults{
Traces: []vm.TransactionTrace{*vmTrace},
NumSteps: 0,
Expand Down Expand Up @@ -295,7 +295,7 @@ func TestTraceBlockTransactions(t *testing.T) {
vmTrace := vm.TransactionTrace{}
require.NoError(t, json.Unmarshal(vmTraceJSON, &vmTrace))
mockVM.EXPECT().Execute(block.Transactions, []core.Class{declaredClass.Class}, paidL1Fees, &vm.BlockInfo{Header: header},
gomock.Any(), n, false, false, false).
gomock.Any(), n, false, false, false, false).
Return(vm.ExecutionResults{
DataAvailability: []core.DataAvailability{},
Traces: []vm.TransactionTrace{vmTrace, vmTrace},
Expand Down Expand Up @@ -366,7 +366,7 @@ func TestTraceBlockTransactions(t *testing.T) {
vmTrace := vm.TransactionTrace{}
require.NoError(t, json.Unmarshal(vmTraceJSON, &vmTrace))
mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header},
gomock.Any(), n, false, false, false).
gomock.Any(), n, false, false, false, false).
Return(vm.ExecutionResults{
DataAvailability: []core.DataAvailability{},
Traces: []vm.TransactionTrace{vmTrace},
Expand Down Expand Up @@ -458,7 +458,7 @@ func TestCall(t *testing.T) {
ClassHash: classHash,
Selector: selector,
Calldata: calldata,
}, &vm.BlockInfo{Header: headsHeader}, gomock.Any(), &utils.Mainnet, uint64(1337), "").Return(expectedRes, nil)
}, &vm.BlockInfo{Header: headsHeader}, gomock.Any(), &utils.Mainnet, uint64(1337), "", false).Return(expectedRes, nil)

res, rpcErr := handler.Call(rpc.FunctionCall{
ContractAddress: *contractAddr,
Expand All @@ -480,7 +480,7 @@ func TestCall(t *testing.T) {
Result: []*felt.Felt{utils.HexToFelt(t, rpccore.EntrypointNotFoundFelt)},
ExecutionFailed: true,
}
expectedErr := rpc.MakeContractError(errors.New(rpccore.EntrypointNotFoundFelt))
expectedErr := rpc.MakeContractError(json.RawMessage(rpccore.EntrypointNotFoundFelt))

headsHeader := &core.Header{
Number: 9,
Expand All @@ -490,7 +490,7 @@ func TestCall(t *testing.T) {
mockReader.EXPECT().HeadsHeader().Return(headsHeader, nil)
mockState.EXPECT().ContractClassHash(contractAddr).Return(classHash, nil)
mockReader.EXPECT().Network().Return(n)
mockVM.EXPECT().Call(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedRes, nil)
mockVM.EXPECT().Call(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(expectedRes, nil)

res, rpcErr := handler.Call(rpc.FunctionCall{
ContractAddress: *contractAddr,
Expand Down
9 changes: 4 additions & 5 deletions rpc/v7/estimate_fee.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package rpcv7

import (
"encoding/json"
"errors"
"fmt"
"net/http"

Expand Down Expand Up @@ -112,19 +111,19 @@ func (h *Handler) estimateMessageFee(msg MsgFromL1, id BlockID, f estimateFeeHan
if rpcErr != nil {
if rpcErr.Code == rpccore.ErrTransactionExecutionError.Code {
data := rpcErr.Data.(TransactionExecutionErrorData)
return nil, httpHeader, MakeContractError(errors.New(data.ExecutionError))
return nil, httpHeader, MakeContractError(data.ExecutionError)

Check warning on line 114 in rpc/v7/estimate_fee.go

View check run for this annotation

Codecov / codecov/patch

rpc/v7/estimate_fee.go#L114

Added line #L114 was not covered by tests
}
return nil, httpHeader, rpcErr
}
return &estimates[0], httpHeader, nil
}

type ContractErrorData struct {
RevertError string `json:"revert_error"`
RevertError json.RawMessage `json:"revert_error"`
}

func MakeContractError(err error) *jsonrpc.Error {
func MakeContractError(err json.RawMessage) *jsonrpc.Error {
return rpccore.ErrContractError.CloneWithData(ContractErrorData{
RevertError: err.Error(),
RevertError: err,
})
}
11 changes: 5 additions & 6 deletions rpc/v7/estimate_fee_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package rpcv7_test

import (
"encoding/json"
"errors"
"testing"

"github.com/NethermindEth/juno/core"
Expand Down Expand Up @@ -36,7 +35,7 @@ func TestEstimateFee(t *testing.T) {

blockInfo := vm.BlockInfo{Header: &core.Header{}}
t.Run("ok with zero values", func(t *testing.T) {
mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, false, true).
mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, false, true, false).
Return(vm.ExecutionResults{
OverallFees: []*felt.Felt{},
DataAvailability: []core.DataAvailability{},
Expand All @@ -50,7 +49,7 @@ func TestEstimateFee(t *testing.T) {
})

t.Run("ok with zero values, skip validate", func(t *testing.T) {
mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true).
mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true, false).
Return(vm.ExecutionResults{
OverallFees: []*felt.Felt{},
DataAvailability: []core.DataAvailability{},
Expand All @@ -64,16 +63,16 @@ func TestEstimateFee(t *testing.T) {
})

t.Run("transaction execution error", func(t *testing.T) {
mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true).
mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true, false).
Return(vm.ExecutionResults{}, vm.TransactionExecutionError{
Index: 44,
Cause: errors.New("oops"),
Cause: json.RawMessage("oops"),
})

_, httpHeader, err := handler.EstimateFee([]rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{rpcv7.SkipValidateFlag}, rpcv7.BlockID{Latest: true})
require.Equal(t, rpccore.ErrTransactionExecutionError.CloneWithData(rpcv7.TransactionExecutionErrorData{
TransactionIndex: 44,
ExecutionError: "oops",
ExecutionError: json.RawMessage("oops"),
}), err)
require.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "0")
})
Expand Down
Loading

0 comments on commit 459542c

Please sign in to comment.