diff --git a/adapters/core2p2p/receipt.go b/adapters/core2p2p/receipt.go index 8a3c36f244..76734de675 100644 --- a/adapters/core2p2p/receipt.go +++ b/adapters/core2p2p/receipt.go @@ -107,7 +107,6 @@ func AdaptExecutionResources(er *core.ExecutionResources) *gen.Receipt_Execution var l1Gas, l1DataGas, l2Gas, totalL1Gas, totalL1DataGas *felt.Felt if da := er.DataAvailability; da != nil { // todo(kirill) check that it might be null l1Gas = new(felt.Felt).SetUint64(da.L1Gas) - l2Gas = new(felt.Felt).SetUint64(da.L2Gas) l1DataGas = new(felt.Felt).SetUint64(da.L1DataGas) } if tgs := er.TotalGasConsumed; tgs != nil { diff --git a/adapters/p2p2core/receipt.go b/adapters/p2p2core/receipt.go index e804cca9b8..05753b391b 100644 --- a/adapters/p2p2core/receipt.go +++ b/adapters/p2p2core/receipt.go @@ -58,7 +58,6 @@ func adaptExecutionResources(er *gen.Receipt_ExecutionResources) *core.Execution }, DataAvailability: &core.DataAvailability{ L1Gas: feltToUint64(er.L1Gas), - L2Gas: feltToUint64(er.L2Gas), L1DataGas: feltToUint64(er.L1DataGas), }, MemoryHoles: uint64(er.MemoryHoles), diff --git a/core/transaction.go b/core/transaction.go index 38d2fe67cf..c65bc0d205 100644 --- a/core/transaction.go +++ b/core/transaction.go @@ -105,7 +105,6 @@ type ExecutionResources struct { type DataAvailability struct { L1Gas uint64 L1DataGas uint64 - L2Gas uint64 } type BuiltinInstanceCounter struct { diff --git a/go.mod b/go.mod index 43edd12bb8..ce32056897 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( github.com/ethereum/go-ethereum v1.14.13 github.com/fxamacker/cbor/v2 v2.7.0 github.com/go-playground/validator/v10 v10.24.0 - github.com/hashicorp/go-set/v2 v2.1.0 github.com/jinzhu/copier v0.4.0 github.com/libp2p/go-libp2p v0.38.1 github.com/libp2p/go-libp2p-kad-dht v0.28.2 @@ -37,7 +36,6 @@ require ( google.golang.org/grpc v1.70.0 google.golang.org/protobuf v1.36.4 gopkg.in/yaml.v3 v3.0.1 - nhooyr.io/websocket v1.8.17 ) require ( diff --git a/go.sum b/go.sum index b859dcb231..856423718a 100644 --- a/go.sum +++ b/go.sum @@ -226,8 +226,6 @@ github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpx github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-set/v2 v2.1.0 h1:iERPCQWks+I+4bTgy0CT2myZsCqNgBg79ZHqwniohXo= -github.com/hashicorp/go-set/v2 v2.1.0/go.mod h1:6q4nh8UCVZODn2tJ5RbJi8+ki7pjZBsAEYGt6yaGeTo= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -510,8 +508,6 @@ github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWR github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shoenig/test v0.6.7 h1:k92ohN9VyRfZn0ezNfwamtIBT/5byyfLVktRmL/Jmek= -github.com/shoenig/test v0.6.7/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= github.com/shurcooL/component v0.0.0-20170202220835-f88ec8f54cc4/go.mod h1:XhFIlyj5a1fBNx5aJTbKoIq0mNaPvOagO+HjB3EtxrY= github.com/shurcooL/events v0.0.0-20181021180414-410e4ca65f48/go.mod h1:5u70Mqkb5O5cxEA8nxTsgrgLehJeAw6Oc4Ab1c/P1HM= github.com/shurcooL/github_flavored_markdown v0.0.0-20181002035957-2122de532470/go.mod h1:2dOwnU2uBioM+SGy2aZoq1f/Sd1l9OkAeAUvjSyvgU0= @@ -853,8 +849,6 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= -nhooyr.io/websocket v1.8.17 h1:KEVeLJkUywCKVsnLIDlD/5gtayKp8VoCkksHCGGfT9Y= -nhooyr.io/websocket v1.8.17/go.mod h1:rN9OFWIUwuxg4fR5tELlYC04bXYowCP9GX47ivo2l+c= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2zzQcaEFbx8wA8rck= diff --git a/mocks/mock_vm.go b/mocks/mock_vm.go index 3dc7013599..0b99812d78 100644 --- a/mocks/mock_vm.go +++ b/mocks/mock_vm.go @@ -44,30 +44,27 @@ func (m *MockVM) EXPECT() *MockVMMockRecorder { } // Call mocks base method. -func (m *MockVM) Call(callInfo *vm.CallInfo, blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, maxSteps uint64) ([]*felt.Felt, error) { +func (m *MockVM) Call(callInfo *vm.CallInfo, blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, maxSteps uint64, sierraVersion string) ([]*felt.Felt, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Call", callInfo, blockInfo, state, network, maxSteps) + ret := m.ctrl.Call(m, "Call", callInfo, blockInfo, state, network, maxSteps, sierraVersion) ret0, _ := ret[0].([]*felt.Felt) ret1, _ := ret[1].(error) return ret0, ret1 } // Call indicates an expected call of Call. -func (mr *MockVMMockRecorder) Call(callInfo, blockInfo, state, network, maxSteps any) *gomock.Call { +func (mr *MockVMMockRecorder) Call(callInfo, blockInfo, state, network, maxSteps, sierraVersion any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Call", reflect.TypeOf((*MockVM)(nil).Call), callInfo, blockInfo, state, network, maxSteps) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Call", reflect.TypeOf((*MockVM)(nil).Call), callInfo, blockInfo, state, network, maxSteps, sierraVersion) } // Execute mocks base method. -func (m *MockVM) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool) ([]*felt.Felt, []core.GasConsumed, []vm.TransactionTrace, uint64, error) { +func (m *MockVM) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool) (vm.ExecutionResults, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Execute", txns, declaredClasses, paidFeesOnL1, blockInfo, state, network, skipChargeFee, skipValidate, errOnRevert) - ret0, _ := ret[0].([]*felt.Felt) - ret1, _ := ret[1].([]core.GasConsumed) - ret2, _ := ret[2].([]vm.TransactionTrace) - ret3, _ := ret[3].(uint64) - ret4, _ := ret[4].(error) - return ret0, ret1, ret2, ret3, ret4 + ret0, _ := ret[0].(vm.ExecutionResults) + ret1, _ := ret[1].(error) + return ret0, ret1 } // Execute indicates an expected call of Execute. diff --git a/node/throttled_vm.go b/node/throttled_vm.go index f50c66be1c..04d66a034f 100644 --- a/node/throttled_vm.go +++ b/node/throttled_vm.go @@ -15,31 +15,28 @@ type ThrottledVM struct { func NewThrottledVM(res vm.VM, concurrenyBudget uint, maxQueueLen int32) *ThrottledVM { return &ThrottledVM{ - Throttler: utils.NewThrottler[vm.VM](concurrenyBudget, &res).WithMaxQueueLen(maxQueueLen), + Throttler: utils.NewThrottler(concurrenyBudget, &res).WithMaxQueueLen(maxQueueLen), } } func (tvm *ThrottledVM) Call(callInfo *vm.CallInfo, blockInfo *vm.BlockInfo, state core.StateReader, - network *utils.Network, maxSteps uint64, + network *utils.Network, maxSteps uint64, sierraVersion string, ) ([]*felt.Felt, error) { var ret []*felt.Felt return ret, tvm.Do(func(vm *vm.VM) error { var err error - ret, err = (*vm).Call(callInfo, blockInfo, state, network, maxSteps) + ret, err = (*vm).Call(callInfo, blockInfo, state, network, maxSteps, sierraVersion) 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, -) ([]*felt.Felt, []core.GasConsumed, []vm.TransactionTrace, uint64, error) { - var ret []*felt.Felt - var traces []vm.TransactionTrace - var daGas []core.GasConsumed - var numSteps uint64 - return ret, daGas, traces, numSteps, tvm.Do(func(vm *vm.VM) error { +) (vm.ExecutionResults, error) { + var executionResult vm.ExecutionResults + return executionResult, tvm.Do(func(vm *vm.VM) error { var err error - ret, daGas, traces, numSteps, err = (*vm).Execute(txns, declaredClasses, paidFeesOnL1, blockInfo, state, network, + executionResult, err = (*vm).Execute(txns, declaredClasses, paidFeesOnL1, blockInfo, state, network, skipChargeFee, skipValidate, errOnRevert) return err }) diff --git a/rpc/v6/estimate_fee_test.go b/rpc/v6/estimate_fee_test.go index bc7536ffa1..178c26186a 100644 --- a/rpc/v6/estimate_fee_test.go +++ b/rpc/v6/estimate_fee_test.go @@ -57,7 +57,7 @@ func TestEstimateMessageFee(t *testing.T) { }, gomock.Any(), &utils.Mainnet, gomock.Any(), false, true).DoAndReturn( func(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *vm.BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool, - ) ([]*felt.Felt, []core.GasConsumed, []vm.TransactionTrace, uint64, error) { + ) (vm.ExecutionResults, error) { require.Len(t, txns, 1) assert.NotNil(t, txns[0].(*core.L1HandlerTransaction)) @@ -65,16 +65,21 @@ func TestEstimateMessageFee(t *testing.T) { assert.Len(t, paidFeesOnL1, 1) actualFee := new(felt.Felt).Mul(expectedGasConsumed, blockInfo.Header.L1GasPriceETH) - return []*felt.Felt{actualFee}, []core.GasConsumed{{L1DataGas: 0}}, []vm.TransactionTrace{{ - StateDiff: &vm.StateDiff{ - StorageDiffs: []vm.StorageDiff{}, - Nonces: []vm.Nonce{}, - DeployedContracts: []vm.DeployedContract{}, - DeprecatedDeclaredClasses: []*felt.Felt{}, - DeclaredClasses: []vm.DeclaredClass{}, - ReplacedClasses: []vm.ReplacedClass{}, - }, - }}, 0, nil + return vm.ExecutionResults{ + OverallFees: []*felt.Felt{actualFee}, + DataAvailability: []core.DataAvailability{{L1DataGas: 0}}, + Traces: []vm.TransactionTrace{{ + StateDiff: &vm.StateDiff{ + StorageDiffs: []vm.StorageDiff{}, + Nonces: []vm.Nonce{}, + DeployedContracts: []vm.DeployedContract{}, + DeprecatedDeclaredClasses: []*felt.Felt{}, + DeclaredClasses: []vm.DeclaredClass{}, + ReplacedClasses: []vm.ReplacedClass{}, + }, + }}, + NumSteps: 0, + }, nil }, ) diff --git a/rpc/v6/handlers.go b/rpc/v6/handlers.go index 391b0b4c4d..a866641817 100644 --- a/rpc/v6/handlers.go +++ b/rpc/v6/handlers.go @@ -109,7 +109,7 @@ func (h *Handler) SpecVersion() (string, *jsonrpc.Error) { func (h *Handler) Run(ctx context.Context) error { newHeadsSub := h.syncReader.SubscribeNewHeads().Subscription defer newHeadsSub.Unsubscribe() - feed.Tee[*core.Header](newHeadsSub, h.newHeads) + feed.Tee(newHeadsSub, h.newHeads) <-ctx.Done() h.subscriptions.Range(func(key, value any) bool { sub := value.(*subscription) diff --git a/rpc/v6/simulation.go b/rpc/v6/simulation.go index 2d7b7bd8df..e6afa25e41 100644 --- a/rpc/v6/simulation.go +++ b/rpc/v6/simulation.go @@ -100,7 +100,7 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra Header: header, BlockHashToBeRevealed: blockHashToBeRevealed, } - overallFees, dataGasConsumed, traces, _, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, + executionResults, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, state, h.bcReader.Network(), skipFeeCharge, skipValidate, errOnRevert) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { @@ -112,6 +112,9 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra } return nil, rpccore.ErrUnexpectedError.CloneWithData(err.Error()) } + overallFees := executionResults.OverallFees + dataGasConsumed := executionResults.DataAvailability + traces := executionResults.Traces result := make([]SimulatedTransaction, len(transactions)) for i, overallFee := range overallFees { @@ -137,11 +140,12 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra if !v0_6Response { trace := traces[i] - executionResources := trace.TotalExecutionResources() da := vm.NewDataAvailability(gasConsumed, new(felt.Felt).SetUint64(dataGasConsumed[i].L1DataGas), header.L1DAMode) - executionResources.DataAvailability = &da - traces[i].ExecutionResources = executionResources + traces[i].ExecutionResources = &vm.ExecutionResources{ + ComputationResources: trace.TotalComputationResources(), + DataAvailability: &da, + } } result[i] = SimulatedTransaction{ diff --git a/rpc/v6/simulation_test.go b/rpc/v6/simulation_test.go index f7f370400e..3dfab407d6 100644 --- a/rpc/v6/simulation_test.go +++ b/rpc/v6/simulation_test.go @@ -39,7 +39,12 @@ func TestSimulateTransactions(t *testing.T) { mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, }, mockState, n, true, false, false). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{}, + NumSteps: stepsUsed, + }, nil) _, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}) require.Nil(t, err) @@ -50,7 +55,12 @@ func TestSimulateTransactions(t *testing.T) { mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, }, mockState, n, false, true, false). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{}, + NumSteps: stepsUsed, + }, nil) _, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) require.Nil(t, err) @@ -60,7 +70,7 @@ func TestSimulateTransactions(t *testing.T) { mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, }, mockState, n, false, true, false). - Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ + Return(vm.ExecutionResults{}, vm.TransactionExecutionError{ Index: 44, Cause: errors.New("oops"), }) @@ -74,7 +84,7 @@ func TestSimulateTransactions(t *testing.T) { mockVM.EXPECT().Execute(nilTxns, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, }, mockState, n, false, true, false). - Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ + Return(vm.ExecutionResults{}, vm.TransactionExecutionError{ Index: 44, Cause: errors.New("oops"), }) diff --git a/rpc/v6/trace.go b/rpc/v6/trace.go index 15c6b5191a..27a8254416 100644 --- a/rpc/v6/trace.go +++ b/rpc/v6/trace.go @@ -255,7 +255,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, BlockHashToBeRevealed: blockHashToBeRevealed, } - overallFees, dataGasConsumed, traces, _, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, &blockInfo, state, network, false, + executionResults, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, &blockInfo, state, network, false, false, false) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { @@ -265,6 +265,9 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, // report them as unexpected errors return nil, rpccore.ErrUnexpectedError.CloneWithData(err.Error()) } + overallFees := executionResults.OverallFees + dataGasConsumed := executionResults.DataAvailability + traces := executionResults.Traces result := make([]TracedBlockTransaction, len(traces)) for index, trace := range traces { @@ -293,11 +296,12 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, gasConsumed := new(felt.Felt).Sub(overallFees[index], dataGasFee) gasConsumed = gasConsumed.Div(gasConsumed, gasPrice) // division by zero felt is zero felt - executionResources := trace.TotalExecutionResources() da := vm.NewDataAvailability(gasConsumed, l1DAGas, header.L1DAMode) - executionResources.DataAvailability = &da - traces[index].ExecutionResources = executionResources + traces[index].ExecutionResources = &vm.ExecutionResources{ + ComputationResources: trace.TotalComputationResources(), + DataAvailability: &da, + } } result[index] = TracedBlockTransaction{ TraceRoot: &traces[index], @@ -375,7 +379,7 @@ 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, "") if err != nil { if errors.Is(err, utils.ErrResourceBusy) { return nil, rpccore.ErrInternal.CloneWithData(rpccore.ThrottledVMErr) diff --git a/rpc/v6/trace_test.go b/rpc/v6/trace_test.go index 5e38734ad1..903b0c3fae 100644 --- a/rpc/v6/trace_test.go +++ b/rpc/v6/trace_test.go @@ -139,7 +139,12 @@ 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).Return(nil, []core.GasConsumed{{L1DataGas: 0}}, []vm.TransactionTrace{*vmTrace}, uint64(0), nil) + &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false). + Return(vm.ExecutionResults{ + DataAvailability: []core.DataAvailability{{L1DataGas: 0}}, + Traces: []vm.TransactionTrace{*vmTrace}, + NumSteps: 0, + }, nil) trace, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) @@ -194,7 +199,11 @@ 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).Return(nil, nil, []vm.TransactionTrace{*vmTrace}, uint64(0), nil) + &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false). + Return(vm.ExecutionResults{ + Traces: []vm.TransactionTrace{*vmTrace}, + NumSteps: 0, + }, nil) trace, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) @@ -286,7 +295,12 @@ 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).Return(nil, []core.GasConsumed{}, []vm.TransactionTrace{vmTrace, vmTrace}, 0, nil) + gomock.Any(), n, false, false, false). + Return(vm.ExecutionResults{ + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{vmTrace, vmTrace}, + NumSteps: 0, + }, nil) result, err := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Hash: blockHash}) require.Nil(t, err) @@ -352,7 +366,12 @@ 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).Return(nil, []core.GasConsumed{}, []vm.TransactionTrace{vmTrace}, uint64(0), nil) + gomock.Any(), n, false, false, false). + Return(vm.ExecutionResults{ + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{vmTrace}, + NumSteps: 0, + }, nil) expectedResult := []rpc.TracedBlockTransaction{ { @@ -439,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), "").Return(expectedRes, nil) res, rpcErr := handler.Call(rpc.FunctionCall{ ContractAddress: *contractAddr, diff --git a/rpc/v7/estimate_fee_test.go b/rpc/v7/estimate_fee_test.go index a88eff3d2d..5349e1be0d 100644 --- a/rpc/v7/estimate_fee_test.go +++ b/rpc/v7/estimate_fee_test.go @@ -37,38 +37,38 @@ 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). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, uint64(123), nil).Times(2) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{}, + NumSteps: 123, + }, nil) _, httpHeader, err := handler.EstimateFee([]rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{}, rpcv7.BlockID{Latest: true}) require.Nil(t, err) assert.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "123") - - // TODO: Remove this when v0.7 is removed - _, httpHeader, err = handler.EstimateFee([]rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{}, rpcv7.BlockID{Latest: true}) - require.Nil(t, err) - assert.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "123") }) 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). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, uint64(123), nil).Times(2) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{}, + NumSteps: 123, + }, nil) _, httpHeader, err := handler.EstimateFee([]rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{rpcv7.SkipValidateFlag}, rpcv7.BlockID{Latest: true}) require.Nil(t, err) assert.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "123") - - // TODO: Remove this when v0.7 is removed - _, httpHeader, err = handler.EstimateFee([]rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{rpcv7.SkipValidateFlag}, rpcv7.BlockID{Latest: true}) - require.Nil(t, err) - assert.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "123") }) t.Run("transaction execution error", func(t *testing.T) { mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &blockInfo, mockState, n, true, true, true). - Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ + Return(vm.ExecutionResults{}, vm.TransactionExecutionError{ Index: 44, Cause: errors.New("oops"), - }).Times(2) + }) _, httpHeader, err := handler.EstimateFee([]rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{rpcv7.SkipValidateFlag}, rpcv7.BlockID{Latest: true}) require.Equal(t, rpccore.ErrTransactionExecutionError.CloneWithData(rpcv7.TransactionExecutionErrorData{ @@ -76,14 +76,6 @@ func TestEstimateFee(t *testing.T) { ExecutionError: "oops", }), err) require.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "0") - - // TODO: Remove this when v0.7 is removed - _, 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", - }), err) - require.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "0") }) t.Run("transaction with invalid contract class", func(t *testing.T) { diff --git a/rpc/v7/handlers_test.go b/rpc/v7/handlers_test.go index 9e1f5ed1f6..e8285b6014 100644 --- a/rpc/v7/handlers_test.go +++ b/rpc/v7/handlers_test.go @@ -50,6 +50,7 @@ func TestThrottledVMError(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) mockReader.EXPECT().HeadsHeader().Return(new(core.Header), nil) mockState.EXPECT().ContractClassHash(&felt.Zero).Return(new(felt.Felt), nil) + mockState.EXPECT().Class(new(felt.Felt)).Return(&core.DeclaredClass{Class: &core.Cairo1Class{}}, nil) _, rpcErr := handler.Call(rpcv7.FunctionCall{}, rpcv7.BlockID{Latest: true}) assert.Equal(t, throttledErr, rpcErr.Data) }) diff --git a/rpc/v7/simulation.go b/rpc/v7/simulation.go index 24e68b0f9f..cb4b9c0021 100644 --- a/rpc/v7/simulation.go +++ b/rpc/v7/simulation.go @@ -106,10 +106,13 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra Header: header, BlockHashToBeRevealed: blockHashToBeRevealed, } - overallFees, daGas, traces, numSteps, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, + executionResults, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, state, h.bcReader.Network(), skipFeeCharge, skipValidate, errOnRevert) + httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(executionResults.NumSteps, 10)) - httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(numSteps, 10)) + overallFees := executionResults.OverallFees + daGas := executionResults.DataAvailability + traces := executionResults.Traces if err != nil { if errors.Is(err, utils.ErrResourceBusy) { @@ -161,12 +164,14 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra } trace := traces[i] - executionResources := trace.TotalExecutionResources() - executionResources.DataAvailability = &vm.DataAvailability{ - L1Gas: daGas[i].L1Gas, - L1DataGas: daGas[i].L1DataGas, + + traces[i].ExecutionResources = &vm.ExecutionResources{ + ComputationResources: trace.TotalComputationResources(), + DataAvailability: &vm.DataAvailability{ + L1Gas: daGas[i].L1Gas, + L1DataGas: daGas[i].L1DataGas, + }, } - traces[i].ExecutionResources = executionResources result = append(result, SimulatedTransaction{ TransactionTrace: &traces[i], diff --git a/rpc/v7/simulation_test.go b/rpc/v7/simulation_test.go index fec45aff8d..b925142f10 100644 --- a/rpc/v7/simulation_test.go +++ b/rpc/v7/simulation_test.go @@ -40,7 +40,12 @@ func TestSimulateTransactions(t *testing.T) { mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, }, mockState, n, true, false, false). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{}, + NumSteps: stepsUsed, + }, nil) _, httpHeader, err := handler.SimulateTransactions(rpcv7.BlockID{Latest: true}, []rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{rpcv7.SkipFeeChargeFlag}) require.Nil(t, err) @@ -52,7 +57,12 @@ func TestSimulateTransactions(t *testing.T) { mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, }, mockState, n, false, true, false). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{}, + NumSteps: stepsUsed, + }, nil) _, httpHeader, err := handler.SimulateTransactions(rpcv7.BlockID{Latest: true}, []rpcv7.BroadcastedTransaction{}, []rpcv7.SimulationFlag{rpcv7.SkipValidateFlag}) require.Nil(t, err) @@ -64,7 +74,7 @@ func TestSimulateTransactions(t *testing.T) { mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ Header: headsHeader, }, mockState, n, false, true, false). - Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ + Return(vm.ExecutionResults{}, vm.TransactionExecutionError{ Index: 44, Cause: errors.New("oops"), }) diff --git a/rpc/v7/trace.go b/rpc/v7/trace.go index 5f38054756..6a4f3983b3 100644 --- a/rpc/v7/trace.go +++ b/rpc/v7/trace.go @@ -110,7 +110,16 @@ func adaptFunctionInvocation(snFnInvocation *starknet.FunctionInvocation) *vm.Fu func adaptFeederExecutionResources(resources *starknet.ExecutionResources) *vm.ExecutionResources { builtins := &resources.BuiltinInstanceCounter + var l1Gas, l1DataGas, l2Gas uint64 + if tgs := resources.TotalGasConsumed; tgs != nil { + l1Gas = tgs.L1Gas + l1DataGas = tgs.L1DataGas + l2Gas = tgs.L2Gas + } return &vm.ExecutionResources{ + L1Gas: l1Gas, + L1DataGas: l1DataGas, + L2Gas: l2Gas, ComputationResources: vm.ComputationResources{ Steps: resources.Steps, MemoryHoles: resources.MemoryHoles, @@ -208,6 +217,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) } txDataAvailability := make(map[felt.Felt]vm.DataAvailability, len(block.Receipts)) + txTotalGasConsumed := make(map[felt.Felt]core.GasConsumed, len(block.Receipts)) for _, receipt := range block.Receipts { if receipt.ExecutionResources == nil { continue @@ -219,16 +229,29 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) } txDataAvailability[*receipt.TransactionHash] = da } + if receiptTGS := receipt.ExecutionResources.TotalGasConsumed; receiptTGS != nil { + tgs := core.GasConsumed{ + L1Gas: receiptTGS.L1Gas, + L1DataGas: receiptTGS.L1DataGas, + L2Gas: receiptTGS.L2Gas, + } + txTotalGasConsumed[*receipt.TransactionHash] = tgs + } } // add execution resources on root level for index, trace := range result { - executionResources := trace.TraceRoot.TotalExecutionResources() // fgw doesn't provide this data in traces endpoint // some receipts don't have data availability data in this case we don't da := txDataAvailability[*trace.TransactionHash] - executionResources.DataAvailability = &da - result[index].TraceRoot.ExecutionResources = executionResources + tgs := txTotalGasConsumed[*trace.TransactionHash] + result[index].TraceRoot.ExecutionResources = &vm.ExecutionResources{ + L1Gas: tgs.L1Gas, + L1DataGas: tgs.L1DataGas, + L2Gas: tgs.L2Gas, + ComputationResources: trace.TraceRoot.TotalComputationResources(), + DataAvailability: &da, + } } return result, httpHeader, err @@ -289,10 +312,10 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) BlockHashToBeRevealed: blockHashToBeRevealed, } - _, daGas, traces, numSteps, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, + executionResult, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, &blockInfo, state, network, false, false, false) - httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(numSteps, 10)) + httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(executionResult.NumSteps, 10)) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { @@ -303,16 +326,26 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) return nil, httpHeader, rpccore.ErrUnexpectedError.CloneWithData(err.Error()) } - result := make([]TracedBlockTransaction, 0, len(traces)) - for index, trace := range traces { - executionResources := trace.TotalExecutionResources() - executionResources.DataAvailability = &vm.DataAvailability{ - L1Gas: daGas[index].L1Gas, - L1DataGas: daGas[index].L1DataGas, + result := make([]TracedBlockTransaction, 0, len(executionResult.Traces)) + for index, trace := range executionResult.Traces { + var L1Gas, L1DataGas, L2Gas uint64 + if gc := executionResult.GasConsumed; gc != nil { + L1Gas = gc[index].L1Gas + L1DataGas = gc[index].L1DataGas + L2Gas = gc[index].L2Gas + } + executionResult.Traces[index].ExecutionResources = &vm.ExecutionResources{ + L1Gas: L1Gas, + L1DataGas: L1DataGas, + L2Gas: L2Gas, + ComputationResources: trace.TotalComputationResources(), + DataAvailability: &vm.DataAvailability{ + L1Gas: executionResult.DataAvailability[index].L1Gas, + L1DataGas: executionResult.DataAvailability[index].L1DataGas, + }, } - traces[index].ExecutionResources = executionResources result = append(result, TracedBlockTransaction{ - TraceRoot: &traces[index], + TraceRoot: &executionResult.Traces[index], TransactionHash: block.Transactions[index].Hash(), }) } @@ -369,6 +402,16 @@ func (h *Handler) Call(funcCall FunctionCall, id BlockID) ([]*felt.Felt, *jsonrp return nil, rpccore.ErrContractNotFound } + declaredClass, err := state.Class(classHash) + if err != nil { + return nil, rpccore.ErrClassHashNotFound + } + + var sierraVersion string + if class, ok := declaredClass.Class.(*core.Cairo1Class); ok { + sierraVersion = class.SemanticVersion + } + blockHashToBeRevealed, err := h.getRevealedBlockHash(header.Number) if err != nil { return nil, rpccore.ErrInternal.CloneWithData(err) @@ -382,7 +425,7 @@ 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, sierraVersion) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { return nil, rpccore.ErrInternal.CloneWithData(throttledVMErr) diff --git a/rpc/v7/trace_test.go b/rpc/v7/trace_test.go index 267a0feb49..1b6b620d02 100644 --- a/rpc/v7/trace_test.go +++ b/rpc/v7/trace_test.go @@ -175,13 +175,19 @@ func TestTraceTransaction(t *testing.T) { }`, executionResources) vmTrace := new(vm.TransactionTrace) require.NoError(t, json.Unmarshal(json.RawMessage(vmTraceJSON), vmTrace)) - consumedGas := []core.GasConsumed{{L1Gas: 1, L1DataGas: 0}} + dataGas := []core.DataAvailability{{L1Gas: 1, L1DataGas: 0}} overallFee := []*felt.Felt{new(felt.Felt).SetUint64(1)} stepsUsed := uint64(123) stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, - false).Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, stepsUsed, nil) + false). + Return(vm.ExecutionResults{ + OverallFees: overallFee, + DataAvailability: dataGas, + Traces: []vm.TransactionTrace{*vmTrace}, + NumSteps: stepsUsed, + }, nil) trace, httpHeader, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) @@ -266,13 +272,18 @@ func TestTraceTransaction(t *testing.T) { }`, executionResources) vmTrace := new(vm.TransactionTrace) require.NoError(t, json.Unmarshal(json.RawMessage(vmTraceJSON), vmTrace)) - consumedGas := []core.GasConsumed{{L1Gas: 1, L1DataGas: 0}} + consumedGas := []core.DataAvailability{{L1Gas: 1, L1DataGas: 0}} overallFee := []*felt.Felt{new(felt.Felt).SetUint64(1)} stepsUsed := uint64(123) stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false). - Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: overallFee, + DataAvailability: consumedGas, + Traces: []vm.TransactionTrace{*vmTrace}, + NumSteps: stepsUsed, + }, nil) trace, httpHeader, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) @@ -384,7 +395,11 @@ func TestTraceBlockTransactions(t *testing.T) { 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). - Return(nil, []core.GasConsumed{{}, {}}, []vm.TransactionTrace{vmTrace, vmTrace}, stepsUsed, nil) + Return(vm.ExecutionResults{ + DataAvailability: []core.DataAvailability{{}, {}}, + Traces: []vm.TransactionTrace{vmTrace, vmTrace}, + NumSteps: stepsUsed, + }, nil) result, httpHeader, err := handler.TraceBlockTransactions(context.Background(), rpcv7.BlockID{Hash: blockHash}) require.Nil(t, err) @@ -460,7 +475,11 @@ func TestTraceBlockTransactions(t *testing.T) { stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header}, gomock.Any(), n, false, false, false). - Return(nil, []core.GasConsumed{{}, {}}, []vm.TransactionTrace{vmTrace}, stepsUsed, nil) + Return(vm.ExecutionResults{ + DataAvailability: []core.DataAvailability{{}, {}}, + Traces: []vm.TransactionTrace{vmTrace}, + NumSteps: stepsUsed, + }, nil) expectedResult := []rpcv7.TracedBlockTransaction{ { @@ -542,13 +561,14 @@ func TestCall(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) mockReader.EXPECT().HeadsHeader().Return(headsHeader, nil) mockState.EXPECT().ContractClassHash(contractAddr).Return(classHash, nil) + mockState.EXPECT().Class(classHash).Return(&core.DeclaredClass{Class: &core.Cairo1Class{}}, nil) mockReader.EXPECT().Network().Return(n) mockVM.EXPECT().Call(&vm.CallInfo{ ContractAddress: contractAddr, 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), "").Return(expectedRes, nil) res, rpcErr := handler.Call(rpcv7.FunctionCall{ ContractAddress: *contractAddr, diff --git a/rpc/v8/estimate_fee_test.go b/rpc/v8/estimate_fee_test.go index f10d546ee4..763072c7b9 100644 --- a/rpc/v8/estimate_fee_test.go +++ b/rpc/v8/estimate_fee_test.go @@ -37,7 +37,13 @@ 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). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, uint64(123), nil) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + GasConsumed: []core.GasConsumed{}, + Traces: []vm.TransactionTrace{}, + NumSteps: uint64(123), + }, nil) _, httpHeader, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{}, rpc.BlockID{Latest: true}) require.Nil(t, err) @@ -46,7 +52,13 @@ 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). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, uint64(123), nil) + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + GasConsumed: []core.GasConsumed{}, + Traces: []vm.TransactionTrace{}, + NumSteps: uint64(123), + }, nil) _, httpHeader, err := handler.EstimateFee([]rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}, rpc.BlockID{Latest: true}) require.Nil(t, err) @@ -55,7 +67,7 @@ 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). - Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ + Return(vm.ExecutionResults{}, vm.TransactionExecutionError{ Index: 44, Cause: errors.New("oops"), }) diff --git a/rpc/v8/handlers_test.go b/rpc/v8/handlers_test.go index 0bb0f41cf3..8ecd875cd9 100644 --- a/rpc/v8/handlers_test.go +++ b/rpc/v8/handlers_test.go @@ -50,6 +50,7 @@ func TestThrottledVMError(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) mockReader.EXPECT().HeadsHeader().Return(new(core.Header), nil) mockState.EXPECT().ContractClassHash(&felt.Zero).Return(new(felt.Felt), nil) + mockState.EXPECT().Class(new(felt.Felt)).Return(&core.DeclaredClass{Class: &core.Cairo1Class{}}, nil) _, rpcErr := handler.Call(rpcv8.FunctionCall{}, rpcv8.BlockID{Latest: true}) assert.Equal(t, throttledErr, rpcErr.Data) }) diff --git a/rpc/v8/simulation.go b/rpc/v8/simulation.go index b1dd756977..a2081f94b9 100644 --- a/rpc/v8/simulation.go +++ b/rpc/v8/simulation.go @@ -20,6 +20,7 @@ type SimulationFlag int const ( SkipValidateFlag SimulationFlag = iota + 1 SkipFeeChargeFlag + throttledVMErr = "VM throughput limit reached" ) const ExecutionStepsHeader string = "X-Cairo-Steps" @@ -77,14 +78,48 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra return nil, httpHeader, rpcErr } + network := h.bcReader.Network() + txns, classes, paidFeesOnL1, rpcErr := prepareTransactions(transactions, network) + if rpcErr != nil { + return nil, httpHeader, rpcErr + } + + blockHashToBeRevealed, err := h.getRevealedBlockHash(header.Number) + if err != nil { + return nil, httpHeader, rpccore.ErrInternal.CloneWithData(err) + } + blockInfo := vm.BlockInfo{ + Header: header, + BlockHashToBeRevealed: blockHashToBeRevealed, + } + + executionResults, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, + state, network, skipFeeCharge, skipValidate, errOnRevert) + if err != nil { + return nil, httpHeader, handleExecutionError(err) + } + + httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(executionResults.NumSteps, 10)) + + simulatedTransactions, err := createSimulatedTransactions(executionResults, txns, header) + if err != nil { + return nil, httpHeader, rpccore.ErrInternal.CloneWithData(err) + } + + return simulatedTransactions, httpHeader, nil +} + +func prepareTransactions(transactions []BroadcastedTransaction, network *utils.Network) ( + []core.Transaction, []core.Class, []*felt.Felt, *jsonrpc.Error, +) { txns := make([]core.Transaction, 0, len(transactions)) var classes []core.Class - paidFeesOnL1 := make([]*felt.Felt, 0) + for idx := range transactions { - txn, declaredClass, paidFeeOnL1, aErr := adaptBroadcastedTransaction(&transactions[idx], h.bcReader.Network()) + txn, declaredClass, paidFeeOnL1, aErr := adaptBroadcastedTransaction(&transactions[idx], network) if aErr != nil { - return nil, httpHeader, jsonrpc.Err(jsonrpc.InvalidParams, aErr.Error()) + return nil, nil, nil, jsonrpc.Err(jsonrpc.InvalidParams, aErr.Error()) } if paidFeeOnL1 != nil { @@ -97,81 +132,91 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra } } - blockHashToBeRevealed, err := h.getRevealedBlockHash(header.Number) - if err != nil { - return nil, httpHeader, rpccore.ErrInternal.CloneWithData(err) + return txns, classes, paidFeesOnL1, nil +} + +func handleExecutionError(err error) *jsonrpc.Error { + if errors.Is(err, utils.ErrResourceBusy) { + return rpccore.ErrInternal.CloneWithData(throttledVMErr) } - blockInfo := vm.BlockInfo{ - Header: header, - BlockHashToBeRevealed: blockHashToBeRevealed, + var txnExecutionError vm.TransactionExecutionError + if errors.As(err, &txnExecutionError) { + return makeTransactionExecutionError(&txnExecutionError) } - overallFees, daGas, traces, numSteps, err := h.vm.Execute(txns, classes, paidFeesOnL1, &blockInfo, - state, h.bcReader.Network(), skipFeeCharge, skipValidate, errOnRevert) - httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(numSteps, 10)) + return rpccore.ErrUnexpectedError.CloneWithData(err.Error()) +} - if err != nil { - if errors.Is(err, utils.ErrResourceBusy) { - return nil, httpHeader, rpccore.ErrInternal.CloneWithData(rpccore.ThrottledVMErr) - } - var txnExecutionError vm.TransactionExecutionError - if errors.As(err, &txnExecutionError) { - return nil, httpHeader, makeTransactionExecutionError(&txnExecutionError) - } - return nil, httpHeader, rpccore.ErrUnexpectedError.CloneWithData(err.Error()) +func createSimulatedTransactions( + executionResults vm.ExecutionResults, txns []core.Transaction, header *core.Header, //nolint: gocritic +) ([]SimulatedTransaction, error) { + overallFees := executionResults.OverallFees + traces := executionResults.Traces + gasConsumed := executionResults.GasConsumed + daGas := executionResults.DataAvailability + if len(overallFees) != len(traces) || len(overallFees) != len(gasConsumed) || + len(overallFees) != len(daGas) || len(overallFees) != len(txns) { + return nil, fmt.Errorf("inconsistent lengths: %d overall fees, %d traces, %d gas consumed, %d data availability, %d txns", + len(overallFees), len(traces), len(gasConsumed), len(daGas), len(txns)) } - result := make([]SimulatedTransaction, 0, len(overallFees)) - for i, overallFee := range overallFees { - feeUnit := feeUnit(txns[i]) + l1GasPriceWei := header.L1GasPriceETH + l1GasPriceStrk := header.L1GasPriceSTRK + l2GasPriceWei := &felt.Zero + l2GasPriceStrk := &felt.Zero + l1DataGasPriceWei := &felt.Zero + l1DataGasPriceStrk := &felt.Zero - estimate := calculateFeeEstimate(overallFee, daGas[i].L1DataGas, feeUnit, header) + if gasPrice := header.L2GasPrice; gasPrice != nil { + l2GasPriceWei = gasPrice.PriceInWei + l2GasPriceStrk = gasPrice.PriceInFri + } + if gasPrice := header.L1DataGasPrice; gasPrice != nil { + l1DataGasPriceWei = gasPrice.PriceInWei + l1DataGasPriceStrk = gasPrice.PriceInFri + } + simulatedTransactions := make([]SimulatedTransaction, len(overallFees)) + for i, overallFee := range overallFees { trace := traces[i] - executionResources := trace.TotalExecutionResources() - executionResources.DataAvailability = &vm.DataAvailability{ - L1Gas: daGas[i].L1Gas, - L1DataGas: daGas[i].L1DataGas, + traces[i].ExecutionResources = &vm.ExecutionResources{ + L1Gas: gasConsumed[i].L1Gas, + L1DataGas: gasConsumed[i].L1DataGas, + L2Gas: gasConsumed[i].L2Gas, + ComputationResources: trace.TotalComputationResources(), + DataAvailability: &vm.DataAvailability{ + L1Gas: daGas[i].L1Gas, + L1DataGas: daGas[i].L1DataGas, + }, } - traces[i].ExecutionResources = executionResources - result = append(result, SimulatedTransaction{ - TransactionTrace: &traces[i], - FeeEstimation: estimate, - }) - } - - return result, httpHeader, nil -} - -func calculateFeeEstimate(overallFee *felt.Felt, l1DataGas uint64, feeUnit FeeUnit, header *core.Header) FeeEstimate { - var l1GasPrice, l2GasPrice, l1DataGasPrice *felt.Felt - - switch feeUnit { - case FRI: - l1GasPrice = header.L1GasPriceSTRK - l2GasPrice = header.L2GasPrice.PriceInFri - l1DataGasPrice = header.L1DataGasPrice.PriceInFri - case WEI: - l1GasPrice = header.L1GasPriceETH - l2GasPrice = header.L2GasPrice.PriceInWei - l1DataGasPrice = header.L1DataGasPrice.PriceInWei - } + var l1GasPrice, l2GasPrice, l1DataGasPrice *felt.Felt + feeUnit := feeUnit(txns[i]) + switch feeUnit { + case WEI: + l1GasPrice = l1GasPriceWei + l2GasPrice = l2GasPriceWei + l1DataGasPrice = l1DataGasPriceWei + case FRI: + l1GasPrice = l1GasPriceStrk + l2GasPrice = l2GasPriceStrk + l1DataGasPrice = l1DataGasPriceStrk + } - l1DataGasConsumed := new(felt.Felt).SetUint64(l1DataGas) - dataGasFee := new(felt.Felt).Mul(l1DataGasConsumed, l1DataGasPrice) - l1GasConsumed := new(felt.Felt).Sub(overallFee, dataGasFee) - l1GasConsumed = l1GasConsumed.Div(l1GasConsumed, l1GasPrice) - - return FeeEstimate{ - L1GasConsumed: l1GasConsumed, - L2GasConsumed: &felt.Zero, // TODO: Fix when we have l2 gas price - L1GasPrice: l1GasPrice, - L2GasPrice: l2GasPrice, - L1DataGasConsumed: l1DataGasConsumed, - L1DataGasPrice: l1DataGasPrice, - OverallFee: overallFee, - Unit: utils.Ptr(feeUnit), + simulatedTransactions[i] = SimulatedTransaction{ + TransactionTrace: &traces[i], + FeeEstimation: FeeEstimate{ + L1GasConsumed: new(felt.Felt).SetUint64(gasConsumed[i].L1Gas), + L1GasPrice: l1GasPrice, + L2GasConsumed: new(felt.Felt).SetUint64(gasConsumed[i].L2Gas), + L2GasPrice: l2GasPrice, + L1DataGasConsumed: new(felt.Felt).SetUint64(gasConsumed[i].L1DataGas), + L1DataGasPrice: l1DataGasPrice, + OverallFee: overallFee, + Unit: utils.Ptr(feeUnit), + }, + } } + return simulatedTransactions, nil } type TransactionExecutionErrorData struct { diff --git a/rpc/v8/simulation_pkg_test.go b/rpc/v8/simulation_pkg_test.go index e3311bb4c6..58a2238d6a 100644 --- a/rpc/v8/simulation_pkg_test.go +++ b/rpc/v8/simulation_pkg_test.go @@ -1,40 +1,154 @@ package rpcv8 import ( + "errors" "testing" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" - "github.com/stretchr/testify/assert" + "github.com/NethermindEth/juno/jsonrpc" + "github.com/NethermindEth/juno/rpc/rpccore" + "github.com/NethermindEth/juno/utils" + "github.com/NethermindEth/juno/vm" + "github.com/stretchr/testify/require" ) -func TestCalculateFeeEstimate(t *testing.T) { - l1GasPriceETH := new(felt.Felt).SetUint64(200) - l1GasPriceSTRK := new(felt.Felt).SetUint64(100) - l2GasPrice := &core.GasPrice{ - PriceInWei: new(felt.Felt).SetUint64(100), - PriceInFri: new(felt.Felt).SetUint64(50), +//nolint:dupl +func TestCreateSimulatedTransactions(t *testing.T) { + executionResults := vm.ExecutionResults{ + OverallFees: []*felt.Felt{new(felt.Felt).SetUint64(10), new(felt.Felt).SetUint64(20)}, + DataAvailability: []core.DataAvailability{ + {L1Gas: 5, L1DataGas: 2}, + {L1Gas: 6, L1DataGas: 3}, + }, + GasConsumed: []core.GasConsumed{ + {L1Gas: 100, L1DataGas: 50, L2Gas: 200}, + {L1Gas: 150, L1DataGas: 70, L2Gas: 250}, + }, + Traces: []vm.TransactionTrace{{}, {}}, + NumSteps: 0, } - l1DataGasPrice := &core.GasPrice{ - PriceInWei: new(felt.Felt).SetUint64(10), - PriceInFri: new(felt.Felt).SetUint64(5), + txns := []core.Transaction{ + &core.InvokeTransaction{ + Version: new(core.TransactionVersion).SetUint64(1), + }, + &core.InvokeTransaction{ + Version: new(core.TransactionVersion).SetUint64(3), + }, } header := &core.Header{ - L1GasPriceETH: l1GasPriceETH, - L2GasPrice: l2GasPrice, - L1GasPriceSTRK: l1GasPriceSTRK, - L1DataGasPrice: l1DataGasPrice, + L1GasPriceETH: new(felt.Felt).SetUint64(1), + L1GasPriceSTRK: new(felt.Felt).SetUint64(2), + L2GasPrice: &core.GasPrice{ + PriceInWei: new(felt.Felt).SetUint64(3), + PriceInFri: new(felt.Felt).SetUint64(4), + }, + L1DataGasPrice: &core.GasPrice{ + PriceInWei: new(felt.Felt).SetUint64(5), + PriceInFri: new(felt.Felt).SetUint64(6), + }, + } + + // Successful case + simTxs, err := createSimulatedTransactions(executionResults, txns, header) + require.NoError(t, err) + require.Len(t, simTxs, 2) + expected := []SimulatedTransaction{ + { + TransactionTrace: &vm.TransactionTrace{ + ExecutionResources: &vm.ExecutionResources{ + L1Gas: 100, + L1DataGas: 50, + L2Gas: 200, + DataAvailability: &vm.DataAvailability{ + L1Gas: 5, + L1DataGas: 2, + }, + }, + }, + FeeEstimation: FeeEstimate{ + L1GasConsumed: new(felt.Felt).SetUint64(100), + L1GasPrice: new(felt.Felt).SetUint64(1), + L2GasConsumed: new(felt.Felt).SetUint64(200), + L2GasPrice: new(felt.Felt).SetUint64(3), + L1DataGasConsumed: new(felt.Felt).SetUint64(50), + L1DataGasPrice: new(felt.Felt).SetUint64(5), + OverallFee: new(felt.Felt).SetUint64(10), + Unit: utils.Ptr(WEI), + }, + }, + { + TransactionTrace: &vm.TransactionTrace{ + ExecutionResources: &vm.ExecutionResources{ + L1Gas: 150, + L1DataGas: 70, + L2Gas: 250, + DataAvailability: &vm.DataAvailability{ + L1Gas: 6, + L1DataGas: 3, + }, + }, + }, + FeeEstimation: FeeEstimate{ + L1GasConsumed: new(felt.Felt).SetUint64(150), + L1GasPrice: new(felt.Felt).SetUint64(2), + L2GasConsumed: new(felt.Felt).SetUint64(250), + L2GasPrice: new(felt.Felt).SetUint64(4), + L1DataGasConsumed: new(felt.Felt).SetUint64(70), + L1DataGasPrice: new(felt.Felt).SetUint64(6), + OverallFee: new(felt.Felt).SetUint64(20), + Unit: utils.Ptr(FRI), + }, + }, + } + require.Equal(t, expected, simTxs) + + // Edge case: Inconsistent lengths + executionResults.Traces = []vm.TransactionTrace{{}} + simTxs, err = createSimulatedTransactions(executionResults, txns, header) + require.Error(t, err) + require.Contains(t, err.Error(), "inconsistent lengths") + require.Empty(t, simTxs) + + // Edge case: Empty input + simTxs, err = createSimulatedTransactions(vm.ExecutionResults{}, []core.Transaction{}, header) + require.NoError(t, err) + require.Empty(t, simTxs) +} + +func TestHandleExecutionError(t *testing.T) { + tests := []struct { + name string + err error + jsonRPCError *jsonrpc.Error + }{ + { + name: "Resource Busy Error", + err: utils.ErrResourceBusy, + jsonRPCError: rpccore.ErrInternal.CloneWithData(throttledVMErr), + }, + { + name: "Transaction Execution Error", + err: &vm.TransactionExecutionError{ + Index: 0, + Cause: errors.New("some error"), + }, + jsonRPCError: &jsonrpc.Error{ + Code: rpccore.ErrUnexpectedError.Code, + Message: rpccore.ErrUnexpectedError.Message, + Data: "execute transaction #0: some error", + }, + }, + { + name: "Unexpected Error", + err: errors.New("unexpected error"), + jsonRPCError: rpccore.ErrUnexpectedError.CloneWithData("unexpected error"), + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + require.Equal(t, test.jsonRPCError, handleExecutionError(test.err)) + }) } - l1DataGas := uint64(500) - overallFee := new(felt.Felt).SetUint64(6000) - - feeEstimate := calculateFeeEstimate(overallFee, l1DataGas, FRI, header) - - assert.Equal(t, l1GasPriceSTRK, feeEstimate.L1GasPrice) - assert.Equal(t, l2GasPrice.PriceInFri, feeEstimate.L2GasPrice) - assert.Equal(t, l1DataGasPrice.PriceInFri, feeEstimate.L1DataGasPrice) - assert.Equal(t, overallFee, feeEstimate.OverallFee) - assert.Equal(t, FRI, *feeEstimate.Unit) - assert.Equal(t, new(felt.Felt).SetUint64(35), feeEstimate.L1GasConsumed) - assert.Equal(t, &felt.Zero, feeEstimate.L2GasConsumed) } diff --git a/rpc/v8/simulation_test.go b/rpc/v8/simulation_test.go index b525b67f38..c6d6bf5a5c 100644 --- a/rpc/v8/simulation_test.go +++ b/rpc/v8/simulation_test.go @@ -2,79 +2,159 @@ package rpcv8_test import ( "errors" + "strconv" "testing" "github.com/NethermindEth/juno/core" "github.com/NethermindEth/juno/core/felt" + "github.com/NethermindEth/juno/jsonrpc" "github.com/NethermindEth/juno/mocks" "github.com/NethermindEth/juno/rpc/rpccore" rpc "github.com/NethermindEth/juno/rpc/v8" "github.com/NethermindEth/juno/utils" "github.com/NethermindEth/juno/vm" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) -//nolint:dupl func TestSimulateTransactions(t *testing.T) { - mockCtrl := gomock.NewController(t) - defer mockCtrl.Finish() - + t.Parallel() n := utils.Ptr(utils.Mainnet) - - mockReader := mocks.NewMockReader(mockCtrl) - mockReader.EXPECT().Network().Return(n).AnyTimes() - mockVM := mocks.NewMockVM(mockCtrl) - handler := rpc.New(mockReader, nil, mockVM, "", utils.NewNopZapLogger()) - - mockState := mocks.NewMockStateHistoryReader(mockCtrl) - mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil).AnyTimes() headsHeader := &core.Header{ SequencerAddress: n.BlockHashMetaInfo.FallBackSequencerAddress, + L1GasPriceETH: &felt.Zero, + L1GasPriceSTRK: &felt.Zero, + L1DAMode: 0, + L1DataGasPrice: &core.GasPrice{ + PriceInWei: &felt.Zero, + PriceInFri: &felt.Zero, + }, + L2GasPrice: &core.GasPrice{ + PriceInWei: &felt.Zero, + PriceInFri: &felt.Zero, + }, + } + defaultMockBehavior := func(mockReader *mocks.MockReader, _ *mocks.MockVM, mockState *mocks.MockStateHistoryReader) { + mockReader.EXPECT().Network().Return(n) + mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) + mockReader.EXPECT().HeadsHeader().Return(headsHeader, nil) + } + tests := []struct { + name string + stepsUsed uint64 + err *jsonrpc.Error + mockBehavior func(*mocks.MockReader, *mocks.MockVM, *mocks.MockStateHistoryReader) + simulationFlags []rpc.SimulationFlag + simulatedTxs []rpc.SimulatedTransaction + }{ + { //nolint:dupl + name: "ok with zero values, skip fee", + stepsUsed: 123, + mockBehavior: func(mockReader *mocks.MockReader, mockVM *mocks.MockVM, mockState *mocks.MockStateHistoryReader) { + defaultMockBehavior(mockReader, mockVM, mockState) + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ + Header: headsHeader, + }, mockState, n, true, false, false). + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + GasConsumed: []core.GasConsumed{}, + Traces: []vm.TransactionTrace{}, + NumSteps: uint64(123), + }, nil) + }, + simulationFlags: []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}, + simulatedTxs: []rpc.SimulatedTransaction{}, + }, + { //nolint:dupl + name: "ok with zero values, skip validate", + stepsUsed: 123, + mockBehavior: func(mockReader *mocks.MockReader, mockVM *mocks.MockVM, mockState *mocks.MockStateHistoryReader) { + defaultMockBehavior(mockReader, mockVM, mockState) + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ + Header: headsHeader, + }, mockState, n, false, true, false). + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + GasConsumed: []core.GasConsumed{}, + Traces: []vm.TransactionTrace{}, + NumSteps: uint64(123), + }, nil) + }, + simulationFlags: []rpc.SimulationFlag{rpc.SkipValidateFlag}, + simulatedTxs: []rpc.SimulatedTransaction{}, + }, + { + name: "transaction execution error", + mockBehavior: func(mockReader *mocks.MockReader, mockVM *mocks.MockVM, mockState *mocks.MockStateHistoryReader) { + defaultMockBehavior(mockReader, mockVM, mockState) + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ + Header: headsHeader, + }, mockState, n, false, true, false). + Return(vm.ExecutionResults{}, vm.TransactionExecutionError{ + Index: 44, + Cause: errors.New("oops"), + }) + }, + simulationFlags: []rpc.SimulationFlag{rpc.SkipValidateFlag}, + err: rpccore.ErrTransactionExecutionError.CloneWithData(rpc.TransactionExecutionErrorData{ + TransactionIndex: 44, + ExecutionError: "oops", + }), + }, + { + name: "inconsistent lengths error", + mockBehavior: func(mockReader *mocks.MockReader, mockVM *mocks.MockVM, mockState *mocks.MockStateHistoryReader) { + defaultMockBehavior(mockReader, mockVM, mockState) + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ + Header: headsHeader, + }, mockState, n, false, true, false). + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{&felt.Zero}, + DataAvailability: []core.DataAvailability{{L1Gas: 0}, {L1Gas: 0}}, + GasConsumed: []core.GasConsumed{{L1Gas: 0, L1DataGas: 0, L2Gas: 0}}, + Traces: []vm.TransactionTrace{{}}, + NumSteps: uint64(0), + }, nil) + }, + simulationFlags: []rpc.SimulationFlag{rpc.SkipValidateFlag}, + err: rpccore.ErrInternal.CloneWithData(errors.New( + "inconsistent lengths: 1 overall fees, 1 traces, 1 gas consumed, 2 data availability, 0 txns", + )), + }, } - mockReader.EXPECT().HeadsHeader().Return(headsHeader, nil).AnyTimes() - - t.Run("ok with zero values, skip fee", func(t *testing.T) { - stepsUsed := uint64(123) - mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ - Header: headsHeader, - }, mockState, n, true, false, false). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) - - _, httpHeader, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}) - require.Nil(t, err) - assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "123") - }) - t.Run("ok with zero values, skip validate", func(t *testing.T) { - stepsUsed := uint64(123) - mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ - Header: headsHeader, - }, mockState, n, false, true, false). - Return([]*felt.Felt{}, []core.GasConsumed{}, []vm.TransactionTrace{}, stepsUsed, nil) + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + t.Parallel() + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() - _, httpHeader, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) - require.Nil(t, err) - assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "123") - }) + mockReader := mocks.NewMockReader(mockCtrl) + mockVM := mocks.NewMockVM(mockCtrl) + mockState := mocks.NewMockStateHistoryReader(mockCtrl) - t.Run("transaction execution error", func(t *testing.T) { - t.Run("v0_7, v0_8", func(t *testing.T) { //nolint:dupl - mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ - Header: headsHeader, - }, mockState, n, false, true, false). - Return(nil, nil, nil, uint64(0), vm.TransactionExecutionError{ - Index: 44, - Cause: errors.New("oops"), - }) + test.mockBehavior(mockReader, mockVM, mockState) + handler := rpc.New(mockReader, nil, mockVM, "", utils.NewNopZapLogger()) - _, httpHeader, 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", - }), err) - require.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), "0") + simulatedTxs, httpHeader, err := handler.SimulateTransactions( + rpc.BlockID{Latest: true}, + []rpc.BroadcastedTransaction{}, + test.simulationFlags, + ) + if test.err != nil { + require.Equal(t, test.err, err) + require.Nil(t, simulatedTxs) + return + } + require.Nil(t, err) + require.Equal( + t, + httpHeader.Get(rpc.ExecutionStepsHeader), + strconv.FormatUint(test.stepsUsed, 10), + ) + require.Equal(t, test.simulatedTxs, simulatedTxs) }) - }) + } } diff --git a/rpc/v8/trace.go b/rpc/v8/trace.go index a13bcb9581..73bdca315d 100644 --- a/rpc/v8/trace.go +++ b/rpc/v8/trace.go @@ -208,6 +208,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) } txDataAvailability := make(map[felt.Felt]vm.DataAvailability, len(block.Receipts)) + txTotalGasConsumed := make(map[felt.Felt]core.GasConsumed, len(block.Receipts)) for _, receipt := range block.Receipts { if receipt.ExecutionResources == nil { continue @@ -219,16 +220,29 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) } txDataAvailability[*receipt.TransactionHash] = da } + if receiptTGS := receipt.ExecutionResources.TotalGasConsumed; receiptTGS != nil { + tgs := core.GasConsumed{ + L1Gas: receiptTGS.L1Gas, + L1DataGas: receiptTGS.L1DataGas, + L2Gas: receiptTGS.L2Gas, + } + txTotalGasConsumed[*receipt.TransactionHash] = tgs + } } // add execution resources on root level for index, trace := range result { - executionResources := trace.TraceRoot.TotalExecutionResources() // fgw doesn't provide this data in traces endpoint // some receipts don't have data availability data in this case we don't da := txDataAvailability[*trace.TransactionHash] - executionResources.DataAvailability = &da - result[index].TraceRoot.ExecutionResources = executionResources + tgs := txTotalGasConsumed[*trace.TransactionHash] + result[index].TraceRoot.ExecutionResources = &vm.ExecutionResources{ + L1Gas: tgs.L1Gas, + L1DataGas: tgs.L1DataGas, + L2Gas: tgs.L2Gas, + ComputationResources: trace.TraceRoot.TotalComputationResources(), + DataAvailability: &da, + } } return result, httpHeader, err @@ -289,30 +303,34 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block) BlockHashToBeRevealed: blockHashToBeRevealed, } - _, daGas, traces, numSteps, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, + executionResult, err := h.vm.Execute(block.Transactions, classes, paidFeesOnL1, &blockInfo, state, network, false, false, false) - httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(numSteps, 10)) + httpHeader.Set(ExecutionStepsHeader, strconv.FormatUint(executionResult.NumSteps, 10)) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { - return nil, httpHeader, rpccore.ErrInternal.CloneWithData(rpccore.ThrottledVMErr) + return nil, httpHeader, rpccore.ErrInternal.CloneWithData(throttledVMErr) } // Since we are tracing an existing block, we know that there should be no errors during execution. If we encounter any, // report them as unexpected errors return nil, httpHeader, rpccore.ErrUnexpectedError.CloneWithData(err.Error()) } - result := make([]TracedBlockTransaction, 0, len(traces)) - for index, trace := range traces { - executionResources := trace.TotalExecutionResources() - executionResources.DataAvailability = &vm.DataAvailability{ - L1Gas: daGas[index].L1Gas, - L1DataGas: daGas[index].L1DataGas, + result := make([]TracedBlockTransaction, 0, len(executionResult.Traces)) + for index, trace := range executionResult.Traces { + executionResult.Traces[index].ExecutionResources = &vm.ExecutionResources{ + L1Gas: executionResult.GasConsumed[index].L1Gas, + L1DataGas: executionResult.GasConsumed[index].L1DataGas, + L2Gas: executionResult.GasConsumed[index].L2Gas, + ComputationResources: trace.TotalComputationResources(), + DataAvailability: &vm.DataAvailability{ + L1Gas: executionResult.DataAvailability[index].L1Gas, + L1DataGas: executionResult.DataAvailability[index].L1DataGas, + }, } - traces[index].ExecutionResources = executionResources result = append(result, TracedBlockTransaction{ - TraceRoot: &traces[index], + TraceRoot: &executionResult.Traces[index], TransactionHash: block.Transactions[index].Hash(), }) } @@ -369,6 +387,16 @@ func (h *Handler) Call(funcCall FunctionCall, id BlockID) ([]*felt.Felt, *jsonrp return nil, rpccore.ErrContractNotFound } + declaredClass, err := state.Class(classHash) + if err != nil { + return nil, rpccore.ErrClassHashNotFound + } + + var sierraVersion string + if class, ok := declaredClass.Class.(*core.Cairo1Class); ok { + sierraVersion = class.SemanticVersion + } + blockHashToBeRevealed, err := h.getRevealedBlockHash(header.Number) if err != nil { return nil, rpccore.ErrInternal.CloneWithData(err) @@ -382,10 +410,10 @@ 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, sierraVersion) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { - return nil, rpccore.ErrInternal.CloneWithData(rpccore.ThrottledVMErr) + return nil, rpccore.ErrInternal.CloneWithData(throttledVMErr) } return nil, makeContractError(err) } diff --git a/rpc/v8/trace_test.go b/rpc/v8/trace_test.go index f1f9979185..5244c4f794 100644 --- a/rpc/v8/trace_test.go +++ b/rpc/v8/trace_test.go @@ -175,19 +175,29 @@ func TestTraceTransaction(t *testing.T) { }`, executionResources) vmTrace := new(vm.TransactionTrace) require.NoError(t, json.Unmarshal(json.RawMessage(vmTraceJSON), vmTrace)) - consumedGas := []core.GasConsumed{{L1Gas: 1, L1DataGas: 0}} + da := []core.DataAvailability{{L1Gas: 1, L1DataGas: 0}} + gc := []core.GasConsumed{{L1Gas: 2, L1DataGas: 3, L2Gas: 4}} overallFee := []*felt.Felt{new(felt.Felt).SetUint64(1)} stepsUsed := uint64(123) stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, - false).Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, stepsUsed, nil) + false).Return(vm.ExecutionResults{ + OverallFees: overallFee, + DataAvailability: da, + GasConsumed: gc, + Traces: []vm.TransactionTrace{*vmTrace}, + NumSteps: stepsUsed, + }, nil) trace, httpHeader, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), stepsUsedStr) vmTrace.ExecutionResources = &vm.ExecutionResources{ + L1Gas: 2, + L1DataGas: 3, + L2Gas: 4, ComputationResources: vm.ComputationResources{ Steps: 3, }, @@ -266,19 +276,29 @@ func TestTraceTransaction(t *testing.T) { }`, executionResources) vmTrace := new(vm.TransactionTrace) require.NoError(t, json.Unmarshal(json.RawMessage(vmTraceJSON), vmTrace)) - consumedGas := []core.GasConsumed{{L1Gas: 1, L1DataGas: 0}} + da := []core.DataAvailability{{L1Gas: 1, L1DataGas: 0}} + gc := []core.GasConsumed{{L1Gas: 2, L1DataGas: 3, L2Gas: 4}} overallFee := []*felt.Felt{new(felt.Felt).SetUint64(1)} stepsUsed := uint64(123) stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header}, gomock.Any(), &utils.Mainnet, false, false, false). - Return(overallFee, consumedGas, []vm.TransactionTrace{*vmTrace}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: overallFee, + DataAvailability: da, + GasConsumed: gc, + Traces: []vm.TransactionTrace{*vmTrace}, + NumSteps: stepsUsed, + }, nil) trace, httpHeader, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) assert.Equal(t, httpHeader.Get(rpc.ExecutionStepsHeader), stepsUsedStr) vmTrace.ExecutionResources = &vm.ExecutionResources{ + L1Gas: 2, + L1DataGas: 3, + L2Gas: 4, // other of fields are zero DataAvailability: &vm.DataAvailability{ L1Gas: 1, @@ -384,7 +404,13 @@ func TestTraceBlockTransactions(t *testing.T) { 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). - Return(nil, []core.GasConsumed{{}, {}}, []vm.TransactionTrace{vmTrace, vmTrace}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: nil, + DataAvailability: []core.DataAvailability{{}, {}}, + GasConsumed: []core.GasConsumed{{}, {}}, + Traces: []vm.TransactionTrace{vmTrace, vmTrace}, + NumSteps: stepsUsed, + }, nil) result, httpHeader, err := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Hash: blockHash}) require.Nil(t, err) @@ -460,7 +486,13 @@ func TestTraceBlockTransactions(t *testing.T) { stepsUsedStr := "123" mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, []*felt.Felt{}, &vm.BlockInfo{Header: header}, gomock.Any(), n, false, false, false). - Return(nil, []core.GasConsumed{{}, {}}, []vm.TransactionTrace{vmTrace}, stepsUsed, nil) + Return(vm.ExecutionResults{ + OverallFees: nil, + DataAvailability: []core.DataAvailability{{}, {}}, + GasConsumed: []core.GasConsumed{{}, {}}, + Traces: []vm.TransactionTrace{vmTrace}, + NumSteps: stepsUsed, + }, nil) expectedResult := []rpc.TracedBlockTransaction{ { @@ -542,13 +574,14 @@ func TestCall(t *testing.T) { mockReader.EXPECT().HeadState().Return(mockState, nopCloser, nil) mockReader.EXPECT().HeadsHeader().Return(headsHeader, nil) mockState.EXPECT().ContractClassHash(contractAddr).Return(classHash, nil) + mockState.EXPECT().Class(classHash).Return(&core.DeclaredClass{Class: &core.Cairo1Class{}}, nil) mockReader.EXPECT().Network().Return(n) mockVM.EXPECT().Call(&vm.CallInfo{ ContractAddress: contractAddr, 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), "").Return(expectedRes, nil) res, rpcErr := handler.Call(rpc.FunctionCall{ ContractAddress: *contractAddr, diff --git a/rpc/v8/transaction.go b/rpc/v8/transaction.go index b7ae8932b7..87a597ab63 100644 --- a/rpc/v8/transaction.go +++ b/rpc/v8/transaction.go @@ -6,6 +6,7 @@ import ( "encoding/json" "errors" "fmt" + "strings" "github.com/NethermindEth/juno/adapters/sn2core" "github.com/NethermindEth/juno/clients/gateway" @@ -165,6 +166,7 @@ type Resource uint32 const ( ResourceL1Gas Resource = iota + 1 ResourceL2Gas + ResourceL1DataGas ) func (r Resource) MarshalText() ([]byte, error) { @@ -173,19 +175,24 @@ func (r Resource) MarshalText() ([]byte, error) { return []byte("l1_gas"), nil case ResourceL2Gas: return []byte("l2_gas"), nil + case ResourceL1DataGas: + return []byte("l1_data_gas"), nil default: return nil, fmt.Errorf("unknown Resource %v", r) } } func (r *Resource) UnmarshalJSON(data []byte) error { - switch string(data) { - case `"l1_gas"`: + str := string(data) + switch strings.ToLower(strings.Trim(str, `"`)) { + case "l1_gas": *r = ResourceL1Gas - case `"l2_gas"`: + case "l2_gas": *r = ResourceL2Gas + case "l1_data_gas": + *r = ResourceL1DataGas default: - return fmt.Errorf("unknown Resource: %q", string(data)) + return fmt.Errorf("unknown Resource: %q", str) } return nil } diff --git a/rpc/v8/transaction_test.go b/rpc/v8/transaction_test.go index 01ec8c1eb9..cfb196e604 100644 --- a/rpc/v8/transaction_test.go +++ b/rpc/v8/transaction_test.go @@ -1318,3 +1318,88 @@ func TestTransactionStatus(t *testing.T) { }) } } + +func TestResourceMarshalText(t *testing.T) { + tests := []struct { + name string + resource rpc.Resource + want []byte + err bool + }{ + { + name: "l1 gas", + resource: rpc.ResourceL1Gas, + want: []byte("l1_gas"), + }, + { + name: "l2 gas", + resource: rpc.ResourceL2Gas, + want: []byte("l2_gas"), + }, + { + name: "l1 data gas", + resource: rpc.ResourceL1DataGas, + want: []byte("l1_data_gas"), + }, + { + name: "error", + resource: rpc.Resource(0), + err: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.resource.MarshalText() + if tt.err { + require.Error(t, err) + require.Nil(t, got) + return + } + require.NoError(t, err) + require.Equal(t, tt.want, got) + }) + } +} + +func TestResourceUnmarshalJSON(t *testing.T) { + tests := []struct { + name string + data []byte + want rpc.Resource + err bool + }{ + { + name: "l1 gas", + data: []byte("l1_gas"), + want: rpc.ResourceL1Gas, + }, + { + name: "l2 gas", + data: []byte("l2_gas"), + want: rpc.ResourceL2Gas, + }, + { + name: "l1 data gas", + data: []byte("l1_data_gas"), + want: rpc.ResourceL1DataGas, + }, + { + name: "error", + data: []byte("unknown"), + err: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var got rpc.Resource + err := got.UnmarshalJSON(tt.data) + if tt.err { + require.Error(t, err) + require.Zero(t, got) + return + } + require.NoError(t, err) + require.Equal(t, tt.want, got) + }) + } +} diff --git a/starknet/transaction.go b/starknet/transaction.go index 9b35a083a7..baa81d015d 100644 --- a/starknet/transaction.go +++ b/starknet/transaction.go @@ -220,7 +220,6 @@ type ExecutionResources struct { type DataAvailability struct { L1Gas uint64 `json:"l1_gas"` L1DataGas uint64 `json:"l1_data_gas"` - L2Gas uint64 `json:"l2_gas"` } type BuiltinInstanceCounter struct { diff --git a/vm/class.go b/vm/class.go index bf02b4f74b..65cc0dc179 100644 --- a/vm/class.go +++ b/vm/class.go @@ -11,14 +11,17 @@ import ( func marshalClassInfo(class core.Class) (json.RawMessage, error) { var classInfo struct { - Class any `json:"contract_class"` - AbiLength uint32 `json:"abi_length"` - SierraLength uint32 `json:"sierra_program_length"` + CairoVersion uint32 `json:"cairo_version"` + Class any `json:"contract_class"` + AbiLength uint32 `json:"abi_length"` + SierraLength uint32 `json:"sierra_program_length"` + SierraVersion string `json:"sierra_version"` } switch c := class.(type) { case *core.Cairo0Class: var err error + classInfo.CairoVersion = 0 classInfo.Class, err = core2sn.AdaptCairo0Class(c) if err != nil { return nil, err @@ -30,9 +33,11 @@ func marshalClassInfo(class core.Class) (json.RawMessage, error) { } // we adapt the core type to the feeder type to avoid using JSON tags in core.Class.CompiledClass + classInfo.CairoVersion = 1 classInfo.Class = core2sn.AdaptCompiledClass(c.Compiled) classInfo.AbiLength = uint32(len(c.Abi)) classInfo.SierraLength = uint32(len(c.Program)) + classInfo.SierraVersion = c.SemanticVersion default: return nil, fmt.Errorf("unsupported class type %T", c) } diff --git a/vm/rust/Cargo.toml b/vm/rust/Cargo.toml index f63e1f488f..945496fa19 100644 --- a/vm/rust/Cargo.toml +++ b/vm/rust/Cargo.toml @@ -8,11 +8,12 @@ edition = "2021" [dependencies] serde = "1.0.208" serde_json = { version = "1.0.125", features = ["raw_value"] } -blockifier = "=0.8.0-rc.3" -cairo-lang-runner = { version = "=2.8.5" } -starknet_api = "0.13.0-rc.1" +blockifier = "=0.14.0-rc.0" +cairo-lang-starknet-classes = "=2.10.0-rc.1" +cairo-lang-runner = { version = "2.10.0-rc.0" } +starknet_api = "=0.14.0-rc.0" cairo-vm = "=1.0.1" -starknet-types-core = { version = "0.1.5", features = ["hash", "prime-bigint"] } +starknet-types-core = { version = "0.1.6", features = ["hash", "prime-bigint"] } indexmap = "2.1.0" cached = "0.54.0" once_cell = "1.19.0" diff --git a/vm/rust/versioned_constants_13_0.json b/vm/rust/resources/versioned_constants_0_13_0.json similarity index 68% rename from vm/rust/versioned_constants_13_0.json rename to vm/rust/resources/versioned_constants_0_13_0.json index 103ea7fca0..4ca11cb656 100644 --- a/vm/rust/versioned_constants_13_0.json +++ b/vm/rust/resources/versioned_constants_0_13_0.json @@ -6,6 +6,56 @@ "invoke_tx_max_n_steps": 3000000, "max_recursion_depth": 50, "segment_arena_cells": true, + "disable_cairo0_redeclaration": false, + "enable_stateful_compression": false, + "comprehensive_state_diff": false, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": false, + "enable_reverts": false, + "tx_event_limits": { + "max_data_length": 1000000000, + "max_keys_length": 1000000000, + "max_n_emitted_events": 1000000000 + }, + "deprecated_l2_resource_gas_costs": { + "gas_per_data_felt": [ + 0, + 1 + ], + "event_key_factor": [ + 0, + 1 + ], + "gas_per_code_byte": [ + 0, + 1 + ] + }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 0, + 1 + ], + "event_key_factor": [ + 0, + 1 + ], + "gas_per_code_byte": [ + 0, + 1 + ] + }, "os_constants": { "nop_entry_point_offset": -1, "entry_point_type_external": 0, @@ -20,12 +70,28 @@ "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "default_entry_point_selector": 0, - "block_hash_contract_address": 1, + "validate_max_sierra_gas": 10000000000, + "execute_max_sierra_gas": 10000000000, "stored_block_hash_buffer": 10, "step_gas_cost": 100, - "range_check_gas_cost": 70, + "builtin_gas_costs": { + "range_check": 70, + "keccak": 0, + "pedersen": 0, + "bitwise": 0, + "ecop": 0, + "poseidon": 0, + "add_mod": 0, + "mul_mod": 0, + "ecdsa": 0 + }, "memory_hole_gas_cost": 10, - "initial_gas_cost": { + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "default_initial_gas_cost": { "step_gas_cost": 100000000 }, "entry_point_initial_budget": { @@ -34,124 +100,118 @@ "syscall_base_gas_cost": { "step_gas_cost": 100 }, - "entry_point_gas_cost": { - "entry_point_initial_budget": 1, - "step_gas_cost": 500 - }, - "fee_transfer_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 100 - }, - "transaction_gas_cost": { - "entry_point_gas_cost": 2, - "fee_transfer_gas_cost": 1, - "step_gas_cost": 100 - }, - "call_contract_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10, - "entry_point_gas_cost": 1 - }, - "deploy_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 200, - "entry_point_gas_cost": 1 - }, - "get_block_hash_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "get_execution_info_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10 - }, - "library_call_gas_cost": { - "call_contract_gas_cost": 1 - }, - "replace_class_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "storage_read_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "storage_write_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "emit_event_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10 - }, - "send_message_to_l1_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "secp256k1_add_gas_cost": { - "step_gas_cost": 406, - "range_check_gas_cost": 29 - }, - "secp256k1_get_point_from_x_gas_cost": { - "step_gas_cost": 391, - "range_check_gas_cost": 30, - "memory_hole_gas_cost": 20 - }, - "secp256k1_get_xy_gas_cost": { - "step_gas_cost": 239, - "range_check_gas_cost": 11, - "memory_hole_gas_cost": 40 - }, - "secp256k1_mul_gas_cost": { - "step_gas_cost": 76401, - "range_check_gas_cost": 7045 - }, - "secp256k1_new_gas_cost": { - "step_gas_cost": 475, - "range_check_gas_cost": 35, - "memory_hole_gas_cost": 40 - }, - "secp256r1_add_gas_cost": { - "step_gas_cost": 589, - "range_check_gas_cost": 57 - }, - "secp256r1_get_point_from_x_gas_cost": { - "step_gas_cost": 510, - "range_check_gas_cost": 44, - "memory_hole_gas_cost": 20 - }, - "secp256r1_get_xy_gas_cost": { - "step_gas_cost": 241, - "range_check_gas_cost": 11, - "memory_hole_gas_cost": 40 - }, - "secp256r1_mul_gas_cost": { - "step_gas_cost": 125240, - "range_check_gas_cost": 13961 - }, - "secp256r1_new_gas_cost": { - "step_gas_cost": 594, - "range_check_gas_cost": 49, - "memory_hole_gas_cost": 40 - }, - "keccak_gas_cost": { - "syscall_base_gas_cost": 1 - }, - "keccak_round_cost_gas_cost": 180000, - "sha256_process_block_gas_cost": { - "step_gas_cost": 0, - "range_check_gas_cost": 0, - "syscall_base_gas_cost": 0 - }, "error_block_number_out_of_range": "Block number out of range", "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", "error_invalid_input_len": "Invalid input length", "error_invalid_argument": "Invalid argument", "validated": "VALID", "l1_gas": "L1_GAS", "l2_gas": "L2_GAS", "l1_gas_index": 0, - "l2_gas_index": 1 + "l2_gas_index": 1, + "syscall_gas_costs": { + "call_contract": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 510 + }, + "deploy": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 700 + }, + "get_block_hash": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_execution_info": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "library_call": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 510 + }, + "replace_class": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_read": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_write": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_class_hash_at": { + "step_gas_cost": 0, + "syscall_base_gas_cost": 0 + }, + "emit_event": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "send_message_to_l1": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "secp256k1_add": { + "step_gas_cost": 406, + "range_check": 29 + }, + "secp256k1_get_point_from_x": { + "step_gas_cost": 391, + "range_check": 30, + "memory_hole_gas_cost": 20 + }, + "secp256k1_get_xy": { + "step_gas_cost": 239, + "range_check": 11, + "memory_hole_gas_cost": 40 + }, + "secp256k1_mul": { + "step_gas_cost": 76401, + "range_check": 7045 + }, + "secp256k1_new": { + "step_gas_cost": 475, + "range_check": 35, + "memory_hole_gas_cost": 40 + }, + "secp256r1_add": { + "step_gas_cost": 589, + "range_check": 57 + }, + "secp256r1_get_point_from_x": { + "step_gas_cost": 510, + "range_check": 44, + "memory_hole_gas_cost": 20 + }, + "secp256r1_get_xy": { + "step_gas_cost": 241, + "range_check": 11, + "memory_hole_gas_cost": 40 + }, + "secp256r1_mul": { + "step_gas_cost": 125240, + "range_check": 13961 + }, + "secp256r1_new": { + "step_gas_cost": 594, + "range_check": 49, + "memory_hole_gas_cost": 40 + }, + "keccak": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost": 180000, + "sha256_process_block": { + "step_gas_cost": 0, + "range_check": 0, + "syscall_base_gas_cost": 0 + } + } }, "os_resources": { "execute_syscalls": { @@ -236,7 +296,7 @@ "n_memory_holes": 0, "n_steps": 44 }, - "Keccak": { + "KeccakRound": { "builtin_instance_counter": { "bitwise_builtin": 6, "keccak_builtin": 1, @@ -245,6 +305,11 @@ "n_memory_holes": 0, "n_steps": 381 }, + "Keccak": { + "builtin_instance_counter": {}, + "n_memory_holes": 0, + "n_steps": 0 + }, "LibraryCall": { "builtin_instance_counter": { "range_check_builtin": 19 @@ -353,6 +418,11 @@ "builtin_instance_counter": {}, "n_memory_holes": 0, "n_steps": 46 + }, + "GetClassHashAt": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 } }, "execute_txs_inner": { @@ -492,54 +562,57 @@ } }, "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "100.0.0", "vm_resource_fee_cost": { - "add_mod_builtin": [ - 0, - 1 - ], - "bitwise_builtin": [ - 32, - 100 - ], - "ec_op_builtin": [ - 512, - 100 - ], - "ecdsa_builtin": [ - 1024, - 100 - ], - "keccak_builtin": [ - 1024, - 100 - ], - "mul_mod_builtin": [ - 0, - 1 - ], + "builtins": { + "add_mod_builtin": [ + 0, + 1 + ], + "bitwise_builtin": [ + 32, + 100 + ], + "ec_op_builtin": [ + 512, + 100 + ], + "ecdsa_builtin": [ + 1024, + 100 + ], + "keccak_builtin": [ + 1024, + 100 + ], + "mul_mod_builtin": [ + 0, + 1 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 16, + 100 + ], + "poseidon_builtin": [ + 16, + 100 + ], + "range_check_builtin": [ + 8, + 100 + ], + "range_check96_builtin": [ + 0, + 1 + ] + }, "n_steps": [ 5, 1000 - ], - "output_builtin": [ - 0, - 1 - ], - "pedersen_builtin": [ - 16, - 100 - ], - "poseidon_builtin": [ - 16, - 100 - ], - "range_check_builtin": [ - 8, - 100 - ], - "range_check96_builtin": [ - 0, - 1 ] } } diff --git a/vm/rust/versioned_constants_13_1.json b/vm/rust/resources/versioned_constants_0_13_1.json similarity index 71% rename from vm/rust/versioned_constants_13_1.json rename to vm/rust/resources/versioned_constants_0_13_1.json index 279612a501..f026a9b5e5 100644 --- a/vm/rust/versioned_constants_13_1.json +++ b/vm/rust/resources/versioned_constants_0_13_1.json @@ -9,7 +9,7 @@ "max_contract_bytecode_size": 81920 }, "invoke_tx_max_n_steps": 4000000, - "l2_resource_gas_costs": { + "deprecated_l2_resource_gas_costs": { "gas_per_data_felt": [ 128, 1000 @@ -23,8 +23,39 @@ 1000 ] }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 35000, + 1 + ] + }, "max_recursion_depth": 50, "segment_arena_cells": true, + "disable_cairo0_redeclaration": false, + "enable_stateful_compression": false, + "comprehensive_state_diff": false, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": true, + "enable_reverts": false, "os_constants": { "nop_entry_point_offset": -1, "entry_point_type_external": 0, @@ -39,12 +70,28 @@ "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "default_entry_point_selector": 0, - "block_hash_contract_address": 1, + "validate_max_sierra_gas": 10000000000, + "execute_max_sierra_gas": 10000000000, "stored_block_hash_buffer": 10, "step_gas_cost": 100, - "range_check_gas_cost": 70, + "builtin_gas_costs": { + "range_check": 70, + "keccak": 0, + "pedersen": 0, + "bitwise": 0, + "ecop": 0, + "poseidon": 0, + "add_mod": 0, + "mul_mod": 0, + "ecdsa": 0 + }, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, "memory_hole_gas_cost": 10, - "initial_gas_cost": { + "default_initial_gas_cost": { "step_gas_cost": 100000000 }, "entry_point_initial_budget": { @@ -53,119 +100,10 @@ "syscall_base_gas_cost": { "step_gas_cost": 100 }, - "entry_point_gas_cost": { - "entry_point_initial_budget": 1, - "step_gas_cost": 500 - }, - "fee_transfer_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 100 - }, - "transaction_gas_cost": { - "entry_point_gas_cost": 2, - "fee_transfer_gas_cost": 1, - "step_gas_cost": 100 - }, - "call_contract_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10, - "entry_point_gas_cost": 1 - }, - "deploy_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 200, - "entry_point_gas_cost": 1 - }, - "get_block_hash_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "get_execution_info_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10 - }, - "library_call_gas_cost": { - "call_contract_gas_cost": 1 - }, - "replace_class_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "storage_read_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "storage_write_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "emit_event_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10 - }, - "send_message_to_l1_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "secp256k1_add_gas_cost": { - "step_gas_cost": 406, - "range_check_gas_cost": 29 - }, - "secp256k1_get_point_from_x_gas_cost": { - "step_gas_cost": 391, - "range_check_gas_cost": 30, - "memory_hole_gas_cost": 20 - }, - "secp256k1_get_xy_gas_cost": { - "step_gas_cost": 239, - "range_check_gas_cost": 11, - "memory_hole_gas_cost": 40 - }, - "secp256k1_mul_gas_cost": { - "step_gas_cost": 76501, - "range_check_gas_cost": 7045, - "memory_hole_gas_cost": 2 - }, - "secp256k1_new_gas_cost": { - "step_gas_cost": 475, - "range_check_gas_cost": 35, - "memory_hole_gas_cost": 40 - }, - "secp256r1_add_gas_cost": { - "step_gas_cost": 589, - "range_check_gas_cost": 57 - }, - "secp256r1_get_point_from_x_gas_cost": { - "step_gas_cost": 510, - "range_check_gas_cost": 44, - "memory_hole_gas_cost": 20 - }, - "secp256r1_get_xy_gas_cost": { - "step_gas_cost": 241, - "range_check_gas_cost": 11, - "memory_hole_gas_cost": 40 - }, - "secp256r1_mul_gas_cost": { - "step_gas_cost": 125340, - "range_check_gas_cost": 13961, - "memory_hole_gas_cost": 2 - }, - "secp256r1_new_gas_cost": { - "step_gas_cost": 594, - "range_check_gas_cost": 49, - "memory_hole_gas_cost": 40 - }, - "keccak_gas_cost": { - "syscall_base_gas_cost": 1 - }, - "keccak_round_cost_gas_cost": 180000, - "sha256_process_block_gas_cost": { - "step_gas_cost": 0, - "range_check_gas_cost": 0, - "syscall_base_gas_cost": 0 - }, "error_block_number_out_of_range": "Block number out of range", "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", "error_invalid_input_len": "Invalid input length", "error_invalid_argument": "Invalid argument", "validated": "VALID", @@ -176,6 +114,109 @@ "validate_rounding_consts": { "validate_block_number_rounding": 100, "validate_timestamp_rounding": 3600 + }, + "syscall_gas_costs": { + "call_contract": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 510 + }, + "deploy": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 700 + }, + "get_block_hash": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_execution_info": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "library_call": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 510 + }, + "replace_class": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_read": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_write": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_class_hash_at": { + "step_gas_cost": 0, + "syscall_base_gas_cost": 0 + }, + "emit_event": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "send_message_to_l1": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "secp256k1_add": { + "step_gas_cost": 406, + "range_check": 29 + }, + "secp256k1_get_point_from_x": { + "step_gas_cost": 391, + "range_check": 30, + "memory_hole_gas_cost": 20 + }, + "secp256k1_get_xy": { + "step_gas_cost": 239, + "range_check": 11, + "memory_hole_gas_cost": 40 + }, + "secp256k1_mul": { + "step_gas_cost": 76501, + "range_check": 7045, + "memory_hole_gas_cost": 2 + }, + "secp256k1_new": { + "step_gas_cost": 475, + "range_check": 35, + "memory_hole_gas_cost": 40 + }, + "secp256r1_add": { + "step_gas_cost": 589, + "range_check": 57 + }, + "secp256r1_get_point_from_x": { + "step_gas_cost": 510, + "range_check": 44, + "memory_hole_gas_cost": 20 + }, + "secp256r1_get_xy": { + "step_gas_cost": 241, + "range_check": 11, + "memory_hole_gas_cost": 40 + }, + "secp256r1_mul": { + "step_gas_cost": 125340, + "range_check": 13961, + "memory_hole_gas_cost": 2 + }, + "secp256r1_new": { + "step_gas_cost": 594, + "range_check": 49, + "memory_hole_gas_cost": 40 + }, + "keccak": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost": 180000, + "sha256_process_block": { + "step_gas_cost": 0, + "range_check": 0, + "syscall_base_gas_cost": 0 + } } }, "os_resources": { @@ -271,7 +312,7 @@ "builtin_instance_counter": {}, "n_memory_holes": 0 }, - "Keccak": { + "KeccakRound": { "n_steps": 381, "builtin_instance_counter": { "bitwise_builtin": 6, @@ -280,6 +321,11 @@ }, "n_memory_holes": 0 }, + "Keccak": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, "LibraryCall": { "n_steps": 751, "builtin_instance_counter": { @@ -396,6 +442,11 @@ "range_check_builtin": 1 }, "n_memory_holes": 0 + }, + "GetClassHashAt": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 } }, "execute_txs_inner": { @@ -547,54 +598,57 @@ } }, "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "100.0.0", "vm_resource_fee_cost": { - "add_mod_builtin": [ - 0, - 1 - ], - "bitwise_builtin": [ - 16, - 100 - ], - "ec_op_builtin": [ - 256, - 100 - ], - "ecdsa_builtin": [ - 512, - 100 - ], - "keccak_builtin": [ - 512, - 100 - ], - "mul_mod_builtin": [ - 0, - 1 - ], + "builtins": { + "add_mod_builtin": [ + 0, + 1 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 0, + 1 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 0, + 1 + ] + }, "n_steps": [ 25, 10000 - ], - "output_builtin": [ - 0, - 1 - ], - "pedersen_builtin": [ - 8, - 100 - ], - "poseidon_builtin": [ - 8, - 100 - ], - "range_check_builtin": [ - 4, - 100 - ], - "range_check96_builtin": [ - 0, - 1 ] } } diff --git a/vm/rust/versioned_constants_13_1_1.json b/vm/rust/resources/versioned_constants_0_13_1_1.json similarity index 71% rename from vm/rust/versioned_constants_13_1_1.json rename to vm/rust/resources/versioned_constants_0_13_1_1.json index a80475fa16..c13cc31177 100644 --- a/vm/rust/versioned_constants_13_1_1.json +++ b/vm/rust/resources/versioned_constants_0_13_1_1.json @@ -9,7 +9,7 @@ "max_contract_bytecode_size": 81920 }, "invoke_tx_max_n_steps": 4000000, - "l2_resource_gas_costs": { + "deprecated_l2_resource_gas_costs": { "gas_per_data_felt": [ 128, 1000 @@ -23,8 +23,39 @@ 1000 ] }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 1280, + 1 + ] + }, "max_recursion_depth": 50, "segment_arena_cells": true, + "disable_cairo0_redeclaration": false, + "enable_stateful_compression": false, + "comprehensive_state_diff": false, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": false, + "enable_reverts": false, "os_constants": { "nop_entry_point_offset": -1, "entry_point_type_external": 0, @@ -39,12 +70,28 @@ "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "default_entry_point_selector": 0, - "block_hash_contract_address": 1, + "validate_max_sierra_gas": 10000000000, + "execute_max_sierra_gas": 10000000000, "stored_block_hash_buffer": 10, "step_gas_cost": 100, - "range_check_gas_cost": 70, + "builtin_gas_costs": { + "range_check": 70, + "keccak": 0, + "pedersen": 0, + "bitwise": 0, + "ecop": 0, + "poseidon": 0, + "add_mod": 0, + "mul_mod": 0, + "ecdsa": 0 + }, "memory_hole_gas_cost": 10, - "initial_gas_cost": { + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "default_initial_gas_cost": { "step_gas_cost": 100000000 }, "entry_point_initial_budget": { @@ -53,119 +100,10 @@ "syscall_base_gas_cost": { "step_gas_cost": 100 }, - "entry_point_gas_cost": { - "entry_point_initial_budget": 1, - "step_gas_cost": 500 - }, - "fee_transfer_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 100 - }, - "transaction_gas_cost": { - "entry_point_gas_cost": 2, - "fee_transfer_gas_cost": 1, - "step_gas_cost": 100 - }, - "call_contract_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10, - "entry_point_gas_cost": 1 - }, - "deploy_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 200, - "entry_point_gas_cost": 1 - }, - "get_block_hash_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "get_execution_info_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10 - }, - "library_call_gas_cost": { - "call_contract_gas_cost": 1 - }, - "replace_class_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "storage_read_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "storage_write_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "emit_event_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 10 - }, - "send_message_to_l1_gas_cost": { - "syscall_base_gas_cost": 1, - "step_gas_cost": 50 - }, - "secp256k1_add_gas_cost": { - "step_gas_cost": 406, - "range_check_gas_cost": 29 - }, - "secp256k1_get_point_from_x_gas_cost": { - "step_gas_cost": 391, - "range_check_gas_cost": 30, - "memory_hole_gas_cost": 20 - }, - "secp256k1_get_xy_gas_cost": { - "step_gas_cost": 239, - "range_check_gas_cost": 11, - "memory_hole_gas_cost": 40 - }, - "secp256k1_mul_gas_cost": { - "step_gas_cost": 76501, - "range_check_gas_cost": 7045, - "memory_hole_gas_cost": 2 - }, - "secp256k1_new_gas_cost": { - "step_gas_cost": 475, - "range_check_gas_cost": 35, - "memory_hole_gas_cost": 40 - }, - "secp256r1_add_gas_cost": { - "step_gas_cost": 589, - "range_check_gas_cost": 57 - }, - "secp256r1_get_point_from_x_gas_cost": { - "step_gas_cost": 510, - "range_check_gas_cost": 44, - "memory_hole_gas_cost": 20 - }, - "secp256r1_get_xy_gas_cost": { - "step_gas_cost": 241, - "range_check_gas_cost": 11, - "memory_hole_gas_cost": 40 - }, - "secp256r1_mul_gas_cost": { - "step_gas_cost": 125340, - "range_check_gas_cost": 13961, - "memory_hole_gas_cost": 2 - }, - "secp256r1_new_gas_cost": { - "step_gas_cost": 594, - "range_check_gas_cost": 49, - "memory_hole_gas_cost": 40 - }, - "keccak_gas_cost": { - "syscall_base_gas_cost": 1 - }, - "keccak_round_cost_gas_cost": 180000, - "sha256_process_block_gas_cost": { - "step_gas_cost": 0, - "range_check_gas_cost": 0, - "syscall_base_gas_cost": 0 - }, "error_block_number_out_of_range": "Block number out of range", "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", "error_invalid_input_len": "Invalid input length", "error_invalid_argument": "Invalid argument", "validated": "VALID", @@ -176,6 +114,109 @@ "validate_rounding_consts": { "validate_block_number_rounding": 100, "validate_timestamp_rounding": 3600 + }, + "syscall_gas_costs": { + "call_contract": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 510 + }, + "deploy": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 700 + }, + "get_block_hash": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_execution_info": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "library_call": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 510 + }, + "replace_class": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_read": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "storage_write": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "get_class_hash_at": { + "step_gas_cost": 0, + "syscall_base_gas_cost": 0 + }, + "emit_event": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 10 + }, + "send_message_to_l1": { + "syscall_base_gas_cost": 1, + "step_gas_cost": 50 + }, + "secp256k1_add": { + "step_gas_cost": 406, + "range_check": 29 + }, + "secp256k1_get_point_from_x": { + "step_gas_cost": 391, + "range_check": 30, + "memory_hole_gas_cost": 20 + }, + "secp256k1_get_xy": { + "step_gas_cost": 239, + "range_check": 11, + "memory_hole_gas_cost": 40 + }, + "secp256k1_mul": { + "step_gas_cost": 76501, + "range_check": 7045, + "memory_hole_gas_cost": 2 + }, + "secp256k1_new": { + "step_gas_cost": 475, + "range_check": 35, + "memory_hole_gas_cost": 40 + }, + "secp256r1_add": { + "step_gas_cost": 589, + "range_check": 57 + }, + "secp256r1_get_point_from_x": { + "step_gas_cost": 510, + "range_check": 44, + "memory_hole_gas_cost": 20 + }, + "secp256r1_get_xy": { + "step_gas_cost": 241, + "range_check": 11, + "memory_hole_gas_cost": 40 + }, + "secp256r1_mul": { + "step_gas_cost": 125340, + "range_check": 13961, + "memory_hole_gas_cost": 2 + }, + "secp256r1_new": { + "step_gas_cost": 594, + "range_check": 49, + "memory_hole_gas_cost": 40 + }, + "keccak": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost": 180000, + "sha256_process_block": { + "step_gas_cost": 0, + "range_check": 0, + "syscall_base_gas_cost": 0 + } } }, "os_resources": { @@ -271,7 +312,7 @@ "builtin_instance_counter": {}, "n_memory_holes": 0 }, - "Keccak": { + "KeccakRound": { "n_steps": 381, "builtin_instance_counter": { "bitwise_builtin": 6, @@ -280,6 +321,11 @@ }, "n_memory_holes": 0 }, + "Keccak": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, "LibraryCall": { "n_steps": 751, "builtin_instance_counter": { @@ -396,6 +442,11 @@ "range_check_builtin": 1 }, "n_memory_holes": 0 + }, + "GetClassHashAt": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 } }, "execute_txs_inner": { @@ -547,54 +598,57 @@ } }, "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "100.0.0", "vm_resource_fee_cost": { - "add_mod_builtin": [ - 0, - 1 - ], - "bitwise_builtin": [ - 16, - 100 - ], - "ec_op_builtin": [ - 256, - 100 - ], - "ecdsa_builtin": [ - 512, - 100 - ], - "keccak_builtin": [ - 512, - 100 - ], - "mul_mod_builtin": [ - 0, - 1 - ], + "builtins": { + "add_mod_builtin": [ + 0, + 1 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 0, + 1 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 0, + 1 + ] + }, "n_steps": [ 25, 10000 - ], - "output_builtin": [ - 0, - 1 - ], - "pedersen_builtin": [ - 8, - 100 - ], - "poseidon_builtin": [ - 8, - 100 - ], - "range_check_builtin": [ - 4, - 100 - ], - "range_check96_builtin": [ - 0, - 1 ] } } diff --git a/vm/rust/resources/versioned_constants_0_13_2.json b/vm/rust/resources/versioned_constants_0_13_2.json new file mode 100644 index 0000000000..55eb3185e0 --- /dev/null +++ b/vm/rust/resources/versioned_constants_0_13_2.json @@ -0,0 +1,660 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 10000000, + "deprecated_l2_resource_gas_costs": { + "gas_per_data_felt": [ + 128, + 1000 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 875, + 1000 + ] + }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 35000, + 1 + ] + }, + "disable_cairo0_redeclaration": true, + "enable_stateful_compression": false, + "comprehensive_state_diff": false, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": false, + "enable_reverts": false, + "max_recursion_depth": 50, + "segment_arena_cells": false, + "os_constants": { + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": 0, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "execute_max_sierra_gas": 10000000000, + "default_initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "l1_gas": "L1_GAS", + "l1_gas_index": 0, + "l1_handler_version": 0, + "l2_gas": "L2_GAS", + "l2_gas_index": 1, + "memory_hole_gas_cost": 10, + "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "builtin_gas_costs": { + "range_check": 70, + "keccak": 0, + "pedersen": 0, + "bitwise": 594, + "ecop": 0, + "poseidon": 0, + "add_mod": 0, + "mul_mod": 0, + "ecdsa": 0 + }, + "sierra_array_len_bound": 4294967296, + "step_gas_cost": 100, + "stored_block_hash_buffer": 10, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_max_sierra_gas": 10000000000, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID", + "syscall_gas_costs": { + "call_contract": { + "step_gas_cost": 510, + "syscall_base_gas_cost": 1 + }, + "deploy": { + "step_gas_cost": 700, + "syscall_base_gas_cost": 1 + }, + "emit_event": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "get_block_hash": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_execution_info": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "keccak": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost": 180000, + "library_call": { + "step_gas_cost": 510, + "syscall_base_gas_cost": 1 + }, + "sha256_process_block": { + "step_gas_cost": 1852, + "range_check": 65, + "bitwise": 1115, + "syscall_base_gas_cost": 1 + }, + "replace_class": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "secp256k1_add": { + "range_check": 29, + "step_gas_cost": 406 + }, + "secp256k1_get_point_from_x": { + "memory_hole_gas_cost": 20, + "range_check": 30, + "step_gas_cost": 391 + }, + "secp256k1_get_xy": { + "memory_hole_gas_cost": 40, + "range_check": 11, + "step_gas_cost": 239 + }, + "secp256k1_mul": { + "memory_hole_gas_cost": 2, + "range_check": 7045, + "step_gas_cost": 76501 + }, + "secp256k1_new": { + "memory_hole_gas_cost": 40, + "range_check": 35, + "step_gas_cost": 475 + }, + "secp256r1_add": { + "range_check": 57, + "step_gas_cost": 589 + }, + "secp256r1_get_point_from_x": { + "memory_hole_gas_cost": 20, + "range_check": 44, + "step_gas_cost": 510 + }, + "secp256r1_get_xy": { + "memory_hole_gas_cost": 40, + "range_check": 11, + "step_gas_cost": 241 + }, + "secp256r1_mul": { + "memory_hole_gas_cost": 2, + "range_check": 13961, + "step_gas_cost": 125340 + }, + "secp256r1_new": { + "memory_hole_gas_cost": 40, + "range_check": 49, + "step_gas_cost": 594 + }, + "send_message_to_l1": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_read": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_write": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_class_hash_at": { + "step_gas_cost": 0, + "syscall_base_gas_cost": 0 + } + } + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 827, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1097, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "KeccakRound": { + "n_steps": 381, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 818, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 98, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 410, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 395, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76505, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 461, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 593, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 514, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 209, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125344, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 580, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 141, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "n_steps": 1855, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetClassHashAt": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "deprecated_resources": { + "constant": { + "n_steps": 2973, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 53 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3079, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 58, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "deprecated_resources": { + "constant": { + "n_steps": 4015, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 72 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4137, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 77, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "deprecated_resources": { + "constant": { + "n_steps": 3763, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 69 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3904, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 74, + "poseidon_builtin": 11 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "deprecated_resources": { + "constant": { + "n_steps": 1233, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 16 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "100.0.0", + "vm_resource_fee_cost": { + "builtins": { + "add_mod_builtin": [ + 4, + 100 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 4, + 100 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 4, + 100 + ] + }, + "n_steps": [ + 25, + 10000 + ] + } +} diff --git a/vm/rust/resources/versioned_constants_0_13_2_1.json b/vm/rust/resources/versioned_constants_0_13_2_1.json new file mode 100644 index 0000000000..4364ffc0c6 --- /dev/null +++ b/vm/rust/resources/versioned_constants_0_13_2_1.json @@ -0,0 +1,660 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 10000000, + "deprecated_l2_resource_gas_costs": { + "gas_per_data_felt": [ + 128, + 1000 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 32, + 1000 + ] + }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 1280, + 1 + ] + }, + "disable_cairo0_redeclaration": true, + "enable_stateful_compression": false, + "comprehensive_state_diff": false, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": false, + "max_recursion_depth": 50, + "enable_reverts": false, + "segment_arena_cells": false, + "os_constants": { + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": 0, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "execute_max_sierra_gas": 10000000000, + "default_initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "l1_gas": "L1_GAS", + "l1_gas_index": 0, + "l1_handler_version": 0, + "l2_gas": "L2_GAS", + "l2_gas_index": 1, + "memory_hole_gas_cost": 10, + "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "builtin_gas_costs": { + "range_check": 70, + "keccak": 0, + "pedersen": 0, + "bitwise": 594, + "ecop": 0, + "poseidon": 0, + "add_mod": 0, + "mul_mod": 0, + "ecdsa": 0 + }, + "sierra_array_len_bound": 4294967296, + "step_gas_cost": 100, + "stored_block_hash_buffer": 10, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_max_sierra_gas": 10000000000, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID", + "syscall_gas_costs": { + "call_contract": { + "step_gas_cost": 510, + "syscall_base_gas_cost": 1 + }, + "deploy": { + "step_gas_cost": 700, + "syscall_base_gas_cost": 1 + }, + "emit_event": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "get_block_hash": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_execution_info": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "keccak": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost": 180000, + "library_call": { + "step_gas_cost": 510, + "syscall_base_gas_cost": 1 + }, + "sha256_process_block": { + "step_gas_cost": 1852, + "range_check": 65, + "bitwise": 1115, + "syscall_base_gas_cost": 1 + }, + "replace_class": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "secp256k1_add": { + "range_check": 29, + "step_gas_cost": 406 + }, + "secp256k1_get_point_from_x": { + "memory_hole_gas_cost": 20, + "range_check": 30, + "step_gas_cost": 391 + }, + "secp256k1_get_xy": { + "memory_hole_gas_cost": 40, + "range_check": 11, + "step_gas_cost": 239 + }, + "secp256k1_mul": { + "memory_hole_gas_cost": 2, + "range_check": 7045, + "step_gas_cost": 76501 + }, + "secp256k1_new": { + "memory_hole_gas_cost": 40, + "range_check": 35, + "step_gas_cost": 475 + }, + "secp256r1_add": { + "range_check": 57, + "step_gas_cost": 589 + }, + "secp256r1_get_point_from_x": { + "memory_hole_gas_cost": 20, + "range_check": 44, + "step_gas_cost": 510 + }, + "secp256r1_get_xy": { + "memory_hole_gas_cost": 40, + "range_check": 11, + "step_gas_cost": 241 + }, + "secp256r1_mul": { + "memory_hole_gas_cost": 2, + "range_check": 13961, + "step_gas_cost": 125340 + }, + "secp256r1_new": { + "memory_hole_gas_cost": 40, + "range_check": 49, + "step_gas_cost": 594 + }, + "send_message_to_l1": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_read": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_write": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_class_hash_at": { + "step_gas_cost": 0, + "syscall_base_gas_cost": 0 + } + } + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 827, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1097, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "KeccakRound": { + "n_steps": 381, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 818, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 98, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 410, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 395, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76505, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 461, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 593, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 514, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 209, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125344, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 580, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 141, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "n_steps": 1855, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetClassHashAt": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "deprecated_resources": { + "constant": { + "n_steps": 2973, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 53 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3079, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 58, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "deprecated_resources": { + "constant": { + "n_steps": 4015, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 72 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4137, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 77, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "deprecated_resources": { + "constant": { + "n_steps": 3763, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 69 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3904, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 74, + "poseidon_builtin": 11 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "deprecated_resources": { + "constant": { + "n_steps": 1233, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 16 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "100.0.0", + "vm_resource_fee_cost": { + "builtins": { + "add_mod_builtin": [ + 4, + 100 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 4, + 100 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 4, + 100 + ] + }, + "n_steps": [ + 25, + 10000 + ] + } +} diff --git a/vm/rust/resources/versioned_constants_0_13_3.json b/vm/rust/resources/versioned_constants_0_13_3.json new file mode 100644 index 0000000000..337622362f --- /dev/null +++ b/vm/rust/resources/versioned_constants_0_13_3.json @@ -0,0 +1,660 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 10000000, + "deprecated_l2_resource_gas_costs": { + "gas_per_data_felt": [ + 128, + 1000 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 32, + 1000 + ] + }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 1280, + 1 + ] + }, + "disable_cairo0_redeclaration": true, + "enable_stateful_compression": false, + "comprehensive_state_diff": false, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 0, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": false, + "max_recursion_depth": 50, + "enable_reverts": false, + "segment_arena_cells": false, + "os_constants": { + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": 0, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "execute_max_sierra_gas": 10000000000, + "default_initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "l1_gas": "L1_GAS", + "l1_gas_index": 0, + "l1_handler_version": 0, + "l2_gas": "L2_GAS", + "l2_gas_index": 1, + "memory_hole_gas_cost": 10, + "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "builtin_gas_costs": { + "range_check": 70, + "keccak": 0, + "pedersen": 0, + "bitwise": 594, + "ecop": 0, + "poseidon": 0, + "add_mod": 0, + "mul_mod": 0, + "ecdsa": 0 + }, + "sierra_array_len_bound": 4294967296, + "step_gas_cost": 100, + "stored_block_hash_buffer": 10, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_max_sierra_gas": 10000000000, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID", + "syscall_gas_costs": { + "call_contract": { + "step_gas_cost": 510, + "syscall_base_gas_cost": 1 + }, + "deploy": { + "step_gas_cost": 700, + "syscall_base_gas_cost": 1 + }, + "emit_event": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "get_block_hash": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_execution_info": { + "step_gas_cost": 10, + "syscall_base_gas_cost": 1 + }, + "keccak": { + "syscall_base_gas_cost": 1 + }, + "keccak_round_cost": 180000, + "library_call": { + "step_gas_cost": 510, + "syscall_base_gas_cost": 1 + }, + "sha256_process_block": { + "step_gas_cost": 1852, + "range_check": 65, + "bitwise": 1115, + "syscall_base_gas_cost": 1 + }, + "replace_class": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "secp256k1_add": { + "range_check": 29, + "step_gas_cost": 406 + }, + "secp256k1_get_point_from_x": { + "memory_hole_gas_cost": 20, + "range_check": 30, + "step_gas_cost": 391 + }, + "secp256k1_get_xy": { + "memory_hole_gas_cost": 40, + "range_check": 11, + "step_gas_cost": 239 + }, + "secp256k1_mul": { + "memory_hole_gas_cost": 2, + "range_check": 7045, + "step_gas_cost": 76501 + }, + "secp256k1_new": { + "memory_hole_gas_cost": 40, + "range_check": 35, + "step_gas_cost": 475 + }, + "secp256r1_add": { + "range_check": 57, + "step_gas_cost": 589 + }, + "secp256r1_get_point_from_x": { + "memory_hole_gas_cost": 20, + "range_check": 44, + "step_gas_cost": 510 + }, + "secp256r1_get_xy": { + "memory_hole_gas_cost": 40, + "range_check": 11, + "step_gas_cost": 241 + }, + "secp256r1_mul": { + "memory_hole_gas_cost": 2, + "range_check": 13961, + "step_gas_cost": 125340 + }, + "secp256r1_new": { + "memory_hole_gas_cost": 40, + "range_check": 49, + "step_gas_cost": 594 + }, + "send_message_to_l1": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_read": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "storage_write": { + "step_gas_cost": 50, + "syscall_base_gas_cost": 1 + }, + "get_class_hash_at": { + "step_gas_cost": 0, + "syscall_base_gas_cost": 0 + } + } + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 827, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1097, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "KeccakRound": { + "n_steps": 381, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 818, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 98, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 410, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 395, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76505, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 461, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 593, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 514, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 209, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125344, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 580, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 141, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "n_steps": 1855, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetClassHashAt": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "deprecated_resources": { + "constant": { + "n_steps": 2973, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 53 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3079, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 58, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "deprecated_resources": { + "constant": { + "n_steps": 4015, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 72 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4137, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 77, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "deprecated_resources": { + "constant": { + "n_steps": 3763, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 69 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3904, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 74, + "poseidon_builtin": 11 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "deprecated_resources": { + "constant": { + "n_steps": 1233, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 16 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "100.0.0", + "vm_resource_fee_cost": { + "builtins": { + "add_mod_builtin": [ + 4, + 100 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 4, + 100 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 4, + 100 + ] + }, + "n_steps": [ + 25, + 10000 + ] + } +} \ No newline at end of file diff --git a/vm/rust/resources/versioned_constants_0_13_4.json b/vm/rust/resources/versioned_constants_0_13_4.json new file mode 100644 index 0000000000..6c967161a8 --- /dev/null +++ b/vm/rust/resources/versioned_constants_0_13_4.json @@ -0,0 +1,561 @@ +{ + "tx_event_limits": { + "max_data_length": 300, + "max_keys_length": 50, + "max_n_emitted_events": 1000 + }, + "gateway": { + "max_calldata_length": 5000, + "max_contract_bytecode_size": 81920 + }, + "invoke_tx_max_n_steps": 10000000, + "deprecated_l2_resource_gas_costs": { + "gas_per_data_felt": [ + 128, + 1000 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 32, + 1000 + ] + }, + "archival_data_gas_costs": { + "gas_per_data_felt": [ + 5120, + 1 + ], + "event_key_factor": [ + 2, + 1 + ], + "gas_per_code_byte": [ + 1280, + 1 + ] + }, + "disable_cairo0_redeclaration": true, + "enable_stateful_compression": true, + "comprehensive_state_diff": true, + "allocation_cost": { + "blob_cost": { + "l1_gas": 0, + "l1_data_gas": 32, + "l2_gas": 0 + }, + "gas_cost": { + "l1_gas": 551, + "l1_data_gas": 0, + "l2_gas": 0 + } + }, + "ignore_inner_event_resources": false, + "enable_reverts": true, + "max_recursion_depth": 50, + "segment_arena_cells": false, + "os_constants": { + "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", + "default_entry_point_selector": 0, + "entry_point_initial_budget": { + "step_gas_cost": 100 + }, + "entry_point_type_constructor": 2, + "entry_point_type_external": 0, + "entry_point_type_l1_handler": 1, + "error_block_number_out_of_range": "Block number out of range", + "error_invalid_input_len": "Invalid input length", + "error_invalid_argument": "Invalid argument", + "error_out_of_gas": "Out of gas", + "error_entry_point_failed": "ENTRYPOINT_FAILED", + "error_entry_point_not_found": "ENTRYPOINT_NOT_FOUND", + "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", + "execute_max_sierra_gas": 1000000000, + "default_initial_gas_cost": { + "step_gas_cost": 100000000 + }, + "l1_gas": "L1_GAS", + "l1_gas_index": 0, + "l1_handler_version": 0, + "l2_gas": "L2_GAS", + "l1_data_gas": "L1_DATA", + "l1_data_gas_index": 2, + "l2_gas_index": 1, + "memory_hole_gas_cost": 10, + "nop_entry_point_offset": -1, + "os_contract_addresses": { + "block_hash_contract_address": 1, + "alias_contract_address": 2, + "reserved_contract_address": 3 + }, + "builtin_gas_costs": { + "range_check": 70, + "keccak": 136189, + "pedersen": 4050, + "bitwise": 583, + "ecop": 4085, + "poseidon": 491, + "add_mod": 230, + "mul_mod": 604, + "ecdsa": 10561 + }, + "sierra_array_len_bound": 4294967296, + "step_gas_cost": 100, + "stored_block_hash_buffer": 10, + "syscall_base_gas_cost": { + "step_gas_cost": 100 + }, + "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", + "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", + "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", + "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", + "validate_max_sierra_gas": 100000000, + "validate_rounding_consts": { + "validate_block_number_rounding": 100, + "validate_timestamp_rounding": 3600 + }, + "validated": "VALID" + }, + "os_resources": { + "execute_syscalls": { + "CallContract": { + "n_steps": 866, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "DelegateCall": { + "n_steps": 713, + "builtin_instance_counter": { + "range_check_builtin": 19 + }, + "n_memory_holes": 0 + }, + "DelegateL1Handler": { + "n_steps": 692, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "Deploy": { + "n_steps": 1132, + "builtin_instance_counter": { + "pedersen_builtin": 7, + "range_check_builtin": 18 + }, + "n_memory_holes": 0 + }, + "EmitEvent": { + "n_steps": 61, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetBlockHash": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 2 + }, + "n_memory_holes": 0 + }, + "GetBlockNumber": { + "n_steps": 40, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetBlockTimestamp": { + "n_steps": 38, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetCallerAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetContractAddress": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetExecutionInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetSequencerAddress": { + "n_steps": 34, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "GetTxInfo": { + "n_steps": 64, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetTxSignature": { + "n_steps": 44, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "KeccakRound": { + "n_steps": 281, + "builtin_instance_counter": { + "bitwise_builtin": 6, + "keccak_builtin": 1, + "range_check_builtin": 56 + }, + "n_memory_holes": 0 + }, + "Keccak": { + "n_steps": 100, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "LibraryCall": { + "n_steps": 842, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "LibraryCallL1Handler": { + "n_steps": 659, + "builtin_instance_counter": { + "range_check_builtin": 15 + }, + "n_memory_holes": 0 + }, + "ReplaceClass": { + "n_steps": 104, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Secp256k1Add": { + "n_steps": 410, + "builtin_instance_counter": { + "range_check_builtin": 29 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetPointFromX": { + "n_steps": 395, + "builtin_instance_counter": { + "range_check_builtin": 30 + }, + "n_memory_holes": 0 + }, + "Secp256k1GetXy": { + "n_steps": 207, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256k1Mul": { + "n_steps": 76505, + "builtin_instance_counter": { + "range_check_builtin": 7045 + }, + "n_memory_holes": 0 + }, + "Secp256k1New": { + "n_steps": 461, + "builtin_instance_counter": { + "range_check_builtin": 35 + }, + "n_memory_holes": 0 + }, + "Secp256r1Add": { + "n_steps": 593, + "builtin_instance_counter": { + "range_check_builtin": 57 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetPointFromX": { + "n_steps": 514, + "builtin_instance_counter": { + "range_check_builtin": 44 + }, + "n_memory_holes": 0 + }, + "Secp256r1GetXy": { + "n_steps": 209, + "builtin_instance_counter": { + "range_check_builtin": 11 + }, + "n_memory_holes": 0 + }, + "Secp256r1Mul": { + "n_steps": 125344, + "builtin_instance_counter": { + "range_check_builtin": 13961 + }, + "n_memory_holes": 0 + }, + "Secp256r1New": { + "n_steps": 580, + "builtin_instance_counter": { + "range_check_builtin": 49 + }, + "n_memory_holes": 0 + }, + "SendMessageToL1": { + "n_steps": 141, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "Sha256ProcessBlock": { + "n_steps": 1865, + "builtin_instance_counter": { + "range_check_builtin": 65, + "bitwise_builtin": 1115 + }, + "n_memory_holes": 0 + }, + "StorageRead": { + "n_steps": 87, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "StorageWrite": { + "n_steps": 93, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + }, + "GetClassHashAt": { + "n_steps": 89, + "builtin_instance_counter": { + "range_check_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "execute_txs_inner": { + "Declare": { + "deprecated_resources": { + "constant": { + "n_steps": 3203, + "builtin_instance_counter": { + "pedersen_builtin": 16, + "range_check_builtin": 56, + "poseidon_builtin": 4 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 3346, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 64, + "poseidon_builtin": 14 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + } + } + }, + "DeployAccount": { + "deprecated_resources": { + "constant": { + "n_steps": 4161, + "builtin_instance_counter": { + "pedersen_builtin": 23, + "range_check_builtin": 72 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4321, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 80, + "poseidon_builtin": 10 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 21, + "builtin_instance_counter": { + "pedersen_builtin": 2 + }, + "n_memory_holes": 0 + } + } + }, + "InvokeFunction": { + "deprecated_resources": { + "constant": { + "n_steps": 3918, + "builtin_instance_counter": { + "pedersen_builtin": 14, + "range_check_builtin": 69 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 4102, + "builtin_instance_counter": { + "pedersen_builtin": 4, + "range_check_builtin": 77, + "poseidon_builtin": 11 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 8, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + }, + "L1Handler": { + "deprecated_resources": { + "constant": { + "n_steps": 1279, + "builtin_instance_counter": { + "pedersen_builtin": 11, + "range_check_builtin": 16 + }, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + }, + "resources": { + "constant": { + "n_steps": 0, + "builtin_instance_counter": {}, + "n_memory_holes": 0 + }, + "calldata_factor": { + "n_steps": 13, + "builtin_instance_counter": { + "pedersen_builtin": 1 + }, + "n_memory_holes": 0 + } + } + } + }, + "compute_os_kzg_commitment_info": { + "n_steps": 113, + "builtin_instance_counter": { + "range_check_builtin": 17 + }, + "n_memory_holes": 0 + } + }, + "validate_max_n_steps": 1000000, + "min_sierra_version_for_sierra_gas": "1.7.0", + "vm_resource_fee_cost": { + "builtins": { + "add_mod_builtin": [ + 4, + 100 + ], + "bitwise_builtin": [ + 16, + 100 + ], + "ec_op_builtin": [ + 256, + 100 + ], + "ecdsa_builtin": [ + 512, + 100 + ], + "keccak_builtin": [ + 512, + 100 + ], + "mul_mod_builtin": [ + 4, + 100 + ], + "output_builtin": [ + 0, + 1 + ], + "pedersen_builtin": [ + 8, + 100 + ], + "poseidon_builtin": [ + 8, + 100 + ], + "range_check_builtin": [ + 4, + 100 + ], + "range_check96_builtin": [ + 4, + 100 + ] + }, + "n_steps": [ + 25, + 10000 + ] + } +} \ No newline at end of file diff --git a/vm/rust/src/jsonrpc.rs b/vm/rust/src/jsonrpc.rs index aa84f58a80..554344a15c 100644 --- a/vm/rust/src/jsonrpc.rs +++ b/vm/rust/src/jsonrpc.rs @@ -7,10 +7,11 @@ use blockifier::state::errors::StateError; use blockifier::state::state_api::StateReader; use cairo_vm::types::builtin_name::BuiltinName; use serde::Serialize; +use starknet_api::contract_class::EntryPointType; use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, EthAddress, PatriciaKey}; -use starknet_api::deprecated_contract_class::EntryPointType; -use starknet_api::transaction::{Calldata, EventContent, L2ToL1Payload}; +use starknet_api::transaction::fields::Calldata; use starknet_api::transaction::{DeclareTransaction, Transaction as StarknetApiTransaction}; +use starknet_api::transaction::{EventContent, L2ToL1Payload}; use starknet_types_core::felt::Felt; type StarkFelt = Felt; @@ -122,7 +123,9 @@ pub fn new_transaction_trace( StarknetApiTransaction::Invoke(_) => { trace.validate_invocation = info.validate_call_info.map(|v| v.into()); trace.execute_invocation = match info.revert_error { - Some(str) => Some(ExecuteInvocation::Revert { revert_reason: str }), + Some(err) => Some(ExecuteInvocation::Revert { + revert_reason: err.to_string(), + }), None => info .execute_call_info .map(|v| ExecuteInvocation::Ok(v.into())), @@ -325,7 +328,7 @@ fn make_state_diff( state: &mut TransactionalState>, deprecated_declared_class_hash: Option, ) -> Result { - let diff: CommitmentStateDiff = state.to_state_diff()?.into(); + let diff: CommitmentStateDiff = state.to_state_diff()?.state_maps.into(); let mut deployed_contracts = Vec::new(); let mut replaced_classes = Vec::new(); @@ -334,13 +337,11 @@ fn make_state_diff( let addr: StarkFelt = addr.into(); if existing_class_hash == ClassHash::default() { - #[rustfmt::skip] deployed_contracts.push(DeployedContract { address: addr, class_hash: class_hash.0, }); } else { - #[rustfmt::skip] replaced_classes.push(ReplacedClass { contract_address: addr, class_hash: class_hash.0, diff --git a/vm/rust/src/juno_state_reader.rs b/vm/rust/src/juno_state_reader.rs index ee4ad9734d..ea0c5bb2c1 100644 --- a/vm/rust/src/juno_state_reader.rs +++ b/vm/rust/src/juno_state_reader.rs @@ -1,27 +1,27 @@ use std::{ ffi::{c_char, c_int, c_uchar, c_void, CStr}, slice, + str::FromStr, sync::Mutex, }; -use blockifier::execution::contract_class::ContractClass; +use blockifier::execution::contract_class::RunnableCompiledClass; use blockifier::state::errors::StateError; use blockifier::state::state_api::UpdatableState; use blockifier::{ - execution::contract_class::{ - ClassInfo as BlockifierClassInfo, ContractClassV0, ContractClassV1, - }, state::cached_state::{ContractClassMapping, StateMaps}, state::state_api::{StateReader, StateResult}, }; use cached::{Cached, SizedCache}; +use cairo_lang_starknet_classes::casm_contract_class::CasmContractClass; use once_cell::sync::Lazy; use serde::Deserialize; +use starknet_api::contract_class::{ + ClassInfo as BlockifierClassInfo, ContractClass, SierraVersion, +}; use starknet_api::core::{ClassHash, CompiledClassHash, ContractAddress, Nonce}; use starknet_api::state::StorageKey; use starknet_types_core::felt::Felt; -use std::collections::{HashMap, HashSet}; - type StarkFelt = Felt; extern "C" { @@ -47,12 +47,12 @@ extern "C" { -> *const c_char; } -struct CachedContractClass { - pub definition: ContractClass, +struct CachedRunnableCompiledClass { + pub definition: RunnableCompiledClass, pub cached_on_height: u64, } -static CLASS_CACHE: Lazy>> = +static CLASS_CACHE: Lazy>> = Lazy::new(|| Mutex::new(SizedCache::with_size(128))); pub struct JunoStateReader { @@ -131,7 +131,7 @@ impl StateReader for JunoStateReader { } /// Returns the contract class of the given class hash. - fn get_compiled_contract_class(&self, class_hash: ClassHash) -> StateResult { + fn get_compiled_class(&self, class_hash: ClassHash) -> StateResult { if let Some(cached_class) = CLASS_CACHE.lock().unwrap().cache_get(&class_hash) { // skip the cache if it comes from a height higher than ours. Class might be undefined on the height // that we are reading from right now. @@ -157,24 +157,29 @@ impl StateReader for JunoStateReader { } else { let json_str = unsafe { CStr::from_ptr(ptr) }.to_str().unwrap(); let class_info_res = class_info_from_json_str(json_str); - if let Ok(class_info) = &class_info_res { - CLASS_CACHE.lock().unwrap().cache_set( - class_hash, - CachedContractClass { - definition: class_info.contract_class(), - cached_on_height: self.height, - }, - ); - } unsafe { JunoFree(ptr as *const c_void) }; - class_info_res.map(|ci| ci.contract_class()).map_err(|err| { - StateError::StateReadError(format!( + match class_info_res { + Ok(class) => { + let runnable_compiled_class = + RunnableCompiledClass::try_from(class.contract_class).unwrap(); + CLASS_CACHE.lock().unwrap().cache_set( + class_hash, + CachedRunnableCompiledClass { + // This clone is cheap, it is just a reference copy in the underlying + // RunnableCompiledClass implementation + definition: runnable_compiled_class.clone(), + cached_on_height: self.height, + }, + ); + Ok(runnable_compiled_class) + } + Err(e) => Err(StateError::StateReadError(format!( "parsing JSON string for class hash {}: {}", - class_hash.0, err - )) - }) + class_hash.0, e + ))), + } } } @@ -185,12 +190,7 @@ impl StateReader for JunoStateReader { } impl UpdatableState for JunoStateReader { - fn apply_writes( - &mut self, - _writes: &StateMaps, - _class_hash_to_class: &ContractClassMapping, - _visited_pcs: &HashMap>, - ) { + fn apply_writes(&mut self, _writes: &StateMaps, _class_hash_to_class: &ContractClassMapping) { unimplemented!() } } @@ -206,26 +206,70 @@ pub fn ptr_to_felt(bytes: *const c_uchar) -> StarkFelt { #[derive(Deserialize)] pub struct ClassInfo { + cairo_version: usize, contract_class: Box, sierra_program_length: usize, abi_length: usize, + sierra_version: String, } pub fn class_info_from_json_str(raw_json: &str) -> Result { let class_info: ClassInfo = serde_json::from_str(raw_json) .map_err(|err| format!("failed parsing class info: {:?}", err))?; - let class_def = class_info.contract_class.to_string(); - let mut sierra_len = class_info.sierra_program_length; - let mut abi_len = class_info.abi_length; - let class: ContractClass = - if let Ok(class) = ContractClassV0::try_from_json_string(class_def.as_str()) { + + let class_def = class_info.contract_class.get(); + let sierra_version: SierraVersion; + let sierra_len; + let abi_len; + let class: ContractClass = match class_info.cairo_version { + 0 => { + sierra_version = SierraVersion::DEPRECATED; sierra_len = 0; abi_len = 0; - class.into() - } else if let Ok(class) = ContractClassV1::try_from_json_string(class_def.as_str()) { - class.into() - } else { - return Err("not a valid contract class".to_string()); - }; - Ok(BlockifierClassInfo::new(&class, sierra_len, abi_len).unwrap()) + match parse_deprecated_class_definition(class_def.to_string()) { + Ok(class) => class, + Err(err) => return Err(format!("failed parsing deprecated class: {:?}", err)), + } + } + 1 => { + sierra_version = SierraVersion::from_str(&class_info.sierra_version) + .map_err(|err| format!("failed parsing sierra version: {:?}", err))?; + sierra_len = class_info.sierra_program_length; + abi_len = class_info.abi_length; + match parse_casm_definition(class_def.to_string(), sierra_version.clone()) { + Ok(class) => class, + Err(err) => return Err(format!("failed parsing casm class: {:?}", err)), + } + } + _ => { + return Err(format!( + "unsupported class version: {}", + class_info.cairo_version + )) + } + }; + + BlockifierClassInfo::new(&class, sierra_len, abi_len, sierra_version) + .map_err(|err| format!("failed creating BlockifierClassInfo: {:?}", err)) +} + +pub fn parse_deprecated_class_definition( + definition: String, +) -> anyhow::Result { + let class: starknet_api::deprecated_contract_class::ContractClass = + serde_json::from_str(&definition)?; + + Ok(starknet_api::contract_class::ContractClass::V0(class)) +} + +pub fn parse_casm_definition( + casm_definition: String, + sierra_version: starknet_api::contract_class::SierraVersion, +) -> anyhow::Result { + let class: CasmContractClass = serde_json::from_str(&casm_definition)?; + + Ok(starknet_api::contract_class::ContractClass::V1(( + class, + sierra_version, + ))) } diff --git a/vm/rust/src/lib.rs b/vm/rust/src/lib.rs index b9fd76bdec..bb28455d50 100644 --- a/vm/rust/src/lib.rs +++ b/vm/rust/src/lib.rs @@ -8,24 +8,23 @@ use crate::juno_state_reader::{ptr_to_felt, JunoStateReader}; use std::{ collections::HashMap, ffi::{c_char, c_longlong, c_uchar, c_ulonglong, c_void, CStr, CString}, - num::NonZeroU128, slice, sync::Arc, }; -use blockifier::abi::constants::STORED_BLOCK_HASH_BUFFER; -use blockifier::blockifier::block::{ - pre_process_block, BlockInfo as BlockifierBlockInfo, BlockNumberHashPair, GasPrices, -}; +use anyhow::Result; use blockifier::bouncer::BouncerConfig; use blockifier::fee::{fee_utils, gas_usage}; -use blockifier::transaction::objects::GasVector; +use blockifier::{ + abi::constants::STORED_BLOCK_HASH_BUFFER, + transaction::account_transaction::ExecutionFlags as AccountExecutionFlags, +}; +use blockifier::{ + blockifier::block::pre_process_block, execution::entry_point::SierraGasRevertTracker, +}; use blockifier::{ context::{BlockContext, ChainInfo, FeeTokenAddresses, TransactionContext}, - execution::{ - contract_class::ClassInfo, - entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext}, - }, + execution::entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext}, state::{cached_state::CachedState, state_api::State}, transaction::{ errors::TransactionExecutionError::{ @@ -37,14 +36,26 @@ use blockifier::{ }, versioned_constants::VersionedConstants, }; -use cairo_vm::vm::runners::cairo_runner::ExecutionResources; use juno_state_reader::{class_info_from_json_str, felt_to_byte_array}; use serde::Deserialize; use starknet_api::{ - block::BlockHash, + block::{BlockHash, GasPrice}, + contract_class::{ClassInfo, EntryPointType, SierraVersion}, core::PatriciaKey, - deprecated_contract_class::EntryPointType, - transaction::{Calldata, Fee, Transaction as StarknetApiTransaction, TransactionHash}, + executable_transaction::AccountTransaction, + execution_resources::GasVector, + transaction::{ + fields::{Calldata, Fee, GasVectorComputationMode}, + DeclareTransaction, DeployAccountTransaction, InvokeTransaction, + Transaction as StarknetApiTransaction, TransactionHash, + }, +}; +use starknet_api::{ + block::{ + BlockHashAndNumber, BlockInfo as BlockifierBlockInfo, GasPriceVector, GasPrices, + NonzeroGasPrice, + }, + execution_resources::GasAmount, }; use starknet_api::{ core::{ChainId, ClassHash, ContractAddress, EntryPointSelector}, @@ -52,7 +63,6 @@ use starknet_api::{ }; use starknet_types_core::felt::Felt; use std::str::FromStr; - type StarkFelt = Felt; extern "C" { @@ -60,7 +70,13 @@ extern "C" { fn JunoAppendTrace(reader_handle: usize, json_trace: *const c_void, len: usize); fn JunoAppendResponse(reader_handle: usize, ptr: *const c_uchar); fn JunoAppendActualFee(reader_handle: usize, ptr: *const c_uchar); - fn JunoAppendGasConsumed(reader_handle: usize, ptr: *const c_uchar, ptr: *const c_uchar); + fn JunoAppendDAGas(reader_handle: usize, ptr: *const c_uchar, ptr: *const c_uchar); + fn JunoAppendGasConsumed( + reader_handle: usize, + ptr: *const c_uchar, + ptr: *const c_uchar, + ptr: *const c_uchar, + ); fn JunoAddExecutionSteps(reader_handle: usize, execSteps: c_ulonglong); } @@ -80,13 +96,15 @@ pub struct BlockInfo { pub block_number: c_ulonglong, pub block_timestamp: c_ulonglong, pub sequencer_address: [c_uchar; 32], - pub gas_price_wei: [c_uchar; 32], - pub gas_price_fri: [c_uchar; 32], + pub l1_gas_price_wei: [c_uchar; 32], + pub l1_gas_price_fri: [c_uchar; 32], pub version: *const c_char, pub block_hash_to_be_revealed: [c_uchar; 32], - pub data_gas_price_wei: [c_uchar; 32], - pub data_gas_price_fri: [c_uchar; 32], + pub l1_data_gas_price_wei: [c_uchar; 32], + pub l1_data_gas_price_fri: [c_uchar; 32], pub use_blob_data: c_uchar, + pub l2_gas_price_wei: [c_uchar; 32], + pub l2_gas_price_fri: [c_uchar; 32], } #[no_mangle] @@ -98,6 +116,7 @@ pub extern "C" fn cairoVMCall( chain_id: *const c_char, max_steps: c_ulonglong, concurrency_mode: c_uchar, + sierra_version: *const c_char, ) { let block_info = unsafe { *block_info_ptr }; let call_info = unsafe { *call_info_ptr }; @@ -122,22 +141,24 @@ pub extern "C" fn cairoVMCall( } } + let initial_gas = VersionedConstants::latest_constants().infinite_gas_for_vm_mode(); + let contract_address = + starknet_api::core::ContractAddress(PatriciaKey::try_from(contract_addr_felt).unwrap()); + let entry_point = CallEntryPoint { entry_point_type: EntryPointType::External, entry_point_selector: EntryPointSelector(entry_point_selector_felt), calldata: Calldata(calldata_vec.into()), - storage_address: contract_addr_felt.try_into().unwrap(), + storage_address: contract_address, call_type: CallType::Call, class_hash, - code_address: None, - caller_address: ContractAddress::default(), - initial_gas: get_versioned_constants(block_info.version).tx_initial_gas(), + initial_gas, + ..Default::default() }; let concurrency_mode = concurrency_mode == 1; let mut state = CachedState::new(reader); - let mut resources = ExecutionResources::default(); - let context = EntryPointExecutionContext::new_invoke( + let mut context = EntryPointExecutionContext::new_invoke( Arc::new(TransactionContext { block_context: build_block_context( &mut state, @@ -145,16 +166,15 @@ pub extern "C" fn cairoVMCall( chain_id_str, Some(max_steps), concurrency_mode, - ), + ) + .unwrap(), tx_info: TransactionInfo::Deprecated(DeprecatedTransactionInfo::default()), }), false, + SierraGasRevertTracker::new(GasAmount::from(initial_gas)), ); - if let Err(e) = context { - report_error(reader_handle, e.to_string().as_str(), -1); - return; - } - match entry_point.execute(&mut state, &mut resources, &mut context.unwrap()) { + let mut remaining_gas = entry_point.initial_gas; + match entry_point.execute(&mut state, &mut context, &mut remaining_gas) { Err(e) => report_error(reader_handle, e.to_string().as_str(), -1), Ok(t) => { for data in t.execution.retdata.0 { @@ -229,7 +249,8 @@ pub extern "C" fn cairoVMExecute( chain_id_str, None, concurrency_mode, - ); + ) + .unwrap(); let charge_fee = skip_charge_fee == 0; let validate = skip_validate == 0; @@ -265,12 +286,18 @@ pub extern "C" fn cairoVMExecute( _ => None, }; + let account_execution_flags = AccountExecutionFlags { + only_query: txn_and_query_bit.query_bit, + charge_fee, + validate, + }; + let txn = transaction_from_api( txn_and_query_bit.txn.clone(), txn_and_query_bit.txn_hash, class_info, paid_fee_on_l1, - txn_and_query_bit.query_bit, + account_execution_flags, ); if let Err(e) = txn { report_error(reader_handle, e.to_string().as_str(), txn_index as i64); @@ -278,22 +305,27 @@ pub extern "C" fn cairoVMExecute( } let mut txn_state = CachedState::create_transactional(&mut state); + let minimal_gas_vector: Option; let fee_type; - let minimal_l1_gas_amount_vector: Option; - let res = match txn.unwrap() { - Transaction::AccountTransaction(t) => { + let txn = txn.unwrap(); + let gas_vector_computation_mode = determine_gas_vector_mode(&txn); + + let res = match txn { + Transaction::Account(t) => { + minimal_gas_vector = Some(gas_usage::estimate_minimal_gas_vector( + &block_context, + &t, + &gas_vector_computation_mode, + )); fee_type = t.fee_type(); - minimal_l1_gas_amount_vector = - Some(gas_usage::estimate_minimal_gas_vector(&block_context, &t).unwrap()); - t.execute(&mut txn_state, &block_context, charge_fee, validate) + t.execute(&mut txn_state, &block_context) } - Transaction::L1HandlerTransaction(t) => { + Transaction::L1Handler(t) => { + minimal_gas_vector = None; fee_type = t.fee_type(); - minimal_l1_gas_amount_vector = None; - t.execute(&mut txn_state, &block_context, charge_fee, validate) + t.execute(&mut txn_state, &block_context) } }; - match res { Err(error) => { let err_string = match &error { @@ -325,40 +357,41 @@ pub extern "C" fn cairoVMExecute( } // we are estimating fee, override actual fee calculation - if t.transaction_receipt.fee.0 == 0 { - let minimal_l1_gas_amount_vector = - minimal_l1_gas_amount_vector.unwrap_or_default(); - let gas_consumed = t - .transaction_receipt - .gas - .l1_gas - .max(minimal_l1_gas_amount_vector.l1_gas); - let data_gas_consumed = t - .transaction_receipt + if t.receipt.fee.0 == 0 { + let minimal_gas_vector = minimal_gas_vector.unwrap_or_default(); + let l1_gas_consumed = t.receipt.gas.l1_gas.max(minimal_gas_vector.l1_gas); + let l1_data_gas_consumed = t + .receipt .gas .l1_data_gas - .max(minimal_l1_gas_amount_vector.l1_data_gas); + .max(minimal_gas_vector.l1_data_gas); + let l2_gas_consumed = t.receipt.gas.l2_gas.max(minimal_gas_vector.l2_gas); - t.transaction_receipt.fee = fee_utils::get_fee_by_gas_vector( + t.receipt.fee = fee_utils::get_fee_by_gas_vector( block_context.block_info(), GasVector { - l1_data_gas: data_gas_consumed, - l1_gas: gas_consumed, + l1_data_gas: l1_data_gas_consumed, + l1_gas: l1_gas_consumed, + l2_gas: l2_gas_consumed, }, &fee_type, ) } - let actual_fee: Felt = t.transaction_receipt.fee.0.into(); - let da_gas_l1_gas = t.transaction_receipt.da_gas.l1_gas.into(); - let da_gas_l1_data_gas = t.transaction_receipt.da_gas.l1_data_gas.into(); + let actual_fee: Felt = t.receipt.fee.0.into(); + let da_gas_l1_gas = t.receipt.da_gas.l1_gas.into(); + let da_gas_l1_data_gas = t.receipt.da_gas.l1_data_gas.into(); let execution_steps = t - .transaction_receipt + .receipt .resources + .computation .vm_resources .n_steps .try_into() .unwrap_or(u64::MAX); + let l1_gas_consumed = t.receipt.gas.l1_gas.into(); + let l1_data_gas_consumed = t.receipt.gas.l1_data_gas.into(); + let l2_gas_consumed = t.receipt.gas.l2_gas.into(); let trace = jsonrpc::new_transaction_trace(&txn_and_query_bit.txn, t, &mut txn_state); @@ -373,11 +406,17 @@ pub extern "C" fn cairoVMExecute( unsafe { JunoAppendActualFee(reader_handle, felt_to_byte_array(&actual_fee).as_ptr()); - JunoAppendGasConsumed( + JunoAppendDAGas( reader_handle, felt_to_byte_array(&da_gas_l1_gas).as_ptr(), felt_to_byte_array(&da_gas_l1_data_gas).as_ptr(), ); + JunoAppendGasConsumed( + reader_handle, + felt_to_byte_array(&l1_gas_consumed).as_ptr(), + felt_to_byte_array(&l1_data_gas_consumed).as_ptr(), + felt_to_byte_array(&l2_gas_consumed).as_ptr(), + ); JunoAddExecutionSteps(reader_handle, execution_steps) } append_trace(reader_handle, trace.as_ref().unwrap(), &mut trace_buffer); @@ -387,6 +426,28 @@ pub extern "C" fn cairoVMExecute( } } +fn determine_gas_vector_mode(transaction: &Transaction) -> GasVectorComputationMode { + match &transaction { + Transaction::Account(account_tx) => match &account_tx.tx { + AccountTransaction::Declare(tx) => match &tx.tx { + DeclareTransaction::V3(tx) => tx.resource_bounds.get_gas_vector_computation_mode(), + _ => GasVectorComputationMode::NoL2Gas, + }, + AccountTransaction::DeployAccount(tx) => match &tx.tx { + DeployAccountTransaction::V3(tx) => { + tx.resource_bounds.get_gas_vector_computation_mode() + } + _ => GasVectorComputationMode::NoL2Gas, + }, + AccountTransaction::Invoke(tx) => match &tx.tx { + InvokeTransaction::V3(tx) => tx.resource_bounds.get_gas_vector_computation_mode(), + _ => GasVectorComputationMode::NoL2Gas, + }, + }, + Transaction::L1Handler(_) => GasVectorComputationMode::NoL2Gas, + } +} + fn felt_to_u128(felt: StarkFelt) -> u128 { // todo find Into trait or similar let bytes = felt.to_bytes_be(); @@ -402,7 +463,7 @@ fn transaction_from_api( tx_hash: TransactionHash, class_info: Option, paid_fee_on_l1: Option, - query_bit: bool, + execution_flags: AccountExecutionFlags, ) -> Result { match tx { StarknetApiTransaction::Deploy(_) => { @@ -420,8 +481,15 @@ fn transaction_from_api( _ => {} // all ok }; - Transaction::from_api(tx, tx_hash, class_info, paid_fee_on_l1, None, query_bit) - .map_err(|err| format!("failed to create transaction from api: {:?}", err)) + Transaction::from_api( + tx, + tx_hash, + class_info, + paid_fee_on_l1, + None, + execution_flags, + ) + .map_err(|err| format!("failed to create transaction from api: {:?}", err)) } fn append_trace( @@ -447,24 +515,35 @@ fn report_error(reader_handle: usize, msg: &str, txn_index: i64) { }; } +// NonzeroGasPrice must be greater than zero to successfully execute transaction. +fn gas_price_from_bytes_bonded(bytes: &[c_uchar; 32]) -> Result { + let u128_val = felt_to_u128(StarkFelt::from_bytes_be(bytes)); + Ok(NonzeroGasPrice::new(GasPrice(if u128_val == 0 { + 1 + } else { + u128_val + }))?) +} + fn build_block_context( state: &mut dyn State, block_info: &BlockInfo, chain_id_str: &str, max_steps: Option, _concurrency_mode: bool, -) -> BlockContext { +) -> Result { let sequencer_addr = StarkFelt::from_bytes_be(&block_info.sequencer_address); - let gas_price_wei_felt = StarkFelt::from_bytes_be(&block_info.gas_price_wei); - let gas_price_fri_felt = StarkFelt::from_bytes_be(&block_info.gas_price_fri); - let data_gas_price_wei_felt = StarkFelt::from_bytes_be(&block_info.data_gas_price_wei); - let data_gas_price_fri_felt = StarkFelt::from_bytes_be(&block_info.data_gas_price_fri); - let default_gas_price = NonZeroU128::new(1).unwrap(); - - let mut old_block_number_and_hash: Option = None; + let l1_gas_price_eth = gas_price_from_bytes_bonded(&block_info.l1_gas_price_wei)?; + let l1_gas_price_strk = gas_price_from_bytes_bonded(&block_info.l1_gas_price_fri)?; + let l1_data_gas_price_eth = gas_price_from_bytes_bonded(&block_info.l1_data_gas_price_wei)?; + let l1_data_gas_price_strk = gas_price_from_bytes_bonded(&block_info.l1_data_gas_price_fri)?; + let l2_gas_price_eth = gas_price_from_bytes_bonded(&block_info.l2_gas_price_wei)?; + let l2_gas_price_strk = gas_price_from_bytes_bonded(&block_info.l2_gas_price_fri)?; + + let mut old_block_number_and_hash: Option = None; // STORED_BLOCK_HASH_BUFFER const is 10 for now if block_info.block_number >= STORED_BLOCK_HASH_BUFFER { - old_block_number_and_hash = Some(BlockNumberHashPair { + old_block_number_and_hash = Some(BlockHashAndNumber { number: starknet_api::block::BlockNumber( block_info.block_number - STORED_BLOCK_HASH_BUFFER, ), @@ -483,21 +562,23 @@ fn build_block_context( block_timestamp: starknet_api::block::BlockTimestamp(block_info.block_timestamp), sequencer_address: ContractAddress(PatriciaKey::try_from(sequencer_addr).unwrap()), gas_prices: GasPrices { - eth_l1_gas_price: NonZeroU128::new(felt_to_u128(gas_price_wei_felt)) - .unwrap_or(default_gas_price), - strk_l1_gas_price: NonZeroU128::new(felt_to_u128(gas_price_fri_felt)) - .unwrap_or(default_gas_price), - eth_l1_data_gas_price: NonZeroU128::new(felt_to_u128(data_gas_price_wei_felt)) - .unwrap_or(default_gas_price), - strk_l1_data_gas_price: NonZeroU128::new(felt_to_u128(data_gas_price_fri_felt)) - .unwrap_or(default_gas_price), + eth_gas_prices: GasPriceVector { + l1_gas_price: l1_gas_price_eth, + l1_data_gas_price: l1_data_gas_price_eth, + l2_gas_price: l2_gas_price_eth, + }, + strk_gas_prices: GasPriceVector { + l1_gas_price: l1_gas_price_strk, + l1_data_gas_price: l1_data_gas_price_strk, + l2_gas_price: l2_gas_price_strk, + }, }, use_kzg_da: block_info.use_blob_data == 1, }; let chain_info = ChainInfo { chain_id: ChainId::from(chain_id_str.to_string()), fee_token_addresses: FeeTokenAddresses { - // both addresses are the same for all networks + // Both addresses are the same for all networks eth_fee_token_address: ContractAddress::try_from( StarkHash::from_hex( "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", @@ -515,8 +596,20 @@ fn build_block_context( }, }; - pre_process_block(state, old_block_number_and_hash, block_info.block_number).unwrap(); - BlockContext::new(block_info, chain_info, constants, BouncerConfig::max()) + pre_process_block( + state, + old_block_number_and_hash, + block_info.block_number, + constants.os_constants.as_ref(), + ) + .unwrap(); + + Ok(BlockContext::new( + block_info, + chain_info, + constants, + BouncerConfig::max(), + )) } lazy_static! { @@ -524,19 +617,45 @@ lazy_static! { let mut m = HashMap::new(); m.insert( "0.13.0".to_string(), - serde_json::from_slice(include_bytes!("../versioned_constants_13_0.json")).unwrap(), + serde_json::from_slice(include_bytes!( + "../resources/versioned_constants_0_13_0.json" + )) + .unwrap(), ); m.insert( "0.13.1".to_string(), - serde_json::from_slice(include_bytes!("../versioned_constants_13_1.json")).unwrap(), + serde_json::from_slice(include_bytes!( + "../resources/versioned_constants_0_13_1.json" + )) + .unwrap(), ); m.insert( "0.13.1.1".to_string(), - serde_json::from_slice(include_bytes!("../versioned_constants_13_1_1.json")).unwrap(), + serde_json::from_slice(include_bytes!( + "../resources/versioned_constants_0_13_1_1.json" + )) + .unwrap(), ); m.insert( "0.13.2".to_string(), - serde_json::from_slice(include_bytes!("../versioned_constants_13_2.json")).unwrap(), + serde_json::from_slice(include_bytes!( + "../resources/versioned_constants_0_13_2.json" + )) + .unwrap(), + ); + m.insert( + "0.13.3".to_string(), + serde_json::from_slice(include_bytes!( + "../resources/versioned_constants_0_13_3.json" + )) + .unwrap(), + ); + m.insert( + "0.13.4".to_string(), + serde_json::from_slice(include_bytes!( + "../resources/versioned_constants_0_13_4.json" + )) + .unwrap(), ); m }; @@ -563,6 +682,10 @@ fn get_versioned_constants(version: *const c_char) -> VersionedConstants { CONSTANTS.get(&"0.13.1.1".to_string()).unwrap().to_owned() } else if version < StarknetVersion::from_str("0.13.2.1").unwrap() { CONSTANTS.get(&"0.13.2".to_string()).unwrap().to_owned() + } else if version < StarknetVersion::from_str("0.13.3").unwrap() { + CONSTANTS.get(&"0.13.3".to_string()).unwrap().to_owned() + } else if version < StarknetVersion::from_str("0.13.4").unwrap() { + CONSTANTS.get(&"0.13.4".to_string()).unwrap().to_owned() } else { VersionedConstants::latest_constants().to_owned() } diff --git a/vm/rust/src/versioned_constants.rs b/vm/rust/src/versioned_constants.rs index 61d98ea6cd..1af85efb04 100644 --- a/vm/rust/src/versioned_constants.rs +++ b/vm/rust/src/versioned_constants.rs @@ -1,3 +1,2 @@ use blockifier::versioned_constants::VersionedConstants; use std::ffi::{c_char, c_uchar, c_void, CStr} - diff --git a/vm/rust/versioned_constants_13_2.json b/vm/rust/versioned_constants_13_2.json deleted file mode 100644 index b6a12cee8d..0000000000 --- a/vm/rust/versioned_constants_13_2.json +++ /dev/null @@ -1,608 +0,0 @@ -{ - "tx_event_limits": { - "max_data_length": 300, - "max_keys_length": 50, - "max_n_emitted_events": 1000 - }, - "gateway": { - "max_calldata_length": 5000, - "max_contract_bytecode_size": 81920 - }, - "invoke_tx_max_n_steps": 10000000, - "l2_resource_gas_costs": { - "gas_per_data_felt": [ - 128, - 1000 - ], - "event_key_factor": [ - 2, - 1 - ], - "gas_per_code_byte": [ - 875, - 1000 - ] - }, - "disable_cairo0_redeclaration": true, - "max_recursion_depth": 50, - "segment_arena_cells": false, - "os_constants": { - "block_hash_contract_address": 1, - "call_contract_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 10, - "syscall_base_gas_cost": 1 - }, - "constructor_entry_point_selector": "0x28ffe4ff0f226a9107253e17a904099aa4f63a02a5621de0576e5aa71bc5194", - "default_entry_point_selector": 0, - "deploy_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 200, - "syscall_base_gas_cost": 1 - }, - "emit_event_gas_cost": { - "step_gas_cost": 10, - "syscall_base_gas_cost": 1 - }, - "entry_point_gas_cost": { - "entry_point_initial_budget": 1, - "step_gas_cost": 500 - }, - "entry_point_initial_budget": { - "step_gas_cost": 100 - }, - "entry_point_type_constructor": 2, - "entry_point_type_external": 0, - "entry_point_type_l1_handler": 1, - "error_block_number_out_of_range": "Block number out of range", - "error_invalid_input_len": "Invalid input length", - "error_invalid_argument": "Invalid argument", - "error_out_of_gas": "Out of gas", - "execute_entry_point_selector": "0x15d40a3d6ca2ac30f4031e42be28da9b056fef9bb7357ac5e85627ee876e5ad", - "fee_transfer_gas_cost": { - "entry_point_gas_cost": 1, - "step_gas_cost": 100 - }, - "get_block_hash_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "get_execution_info_gas_cost": { - "step_gas_cost": 10, - "syscall_base_gas_cost": 1 - }, - "initial_gas_cost": { - "step_gas_cost": 100000000 - }, - "keccak_gas_cost": { - "syscall_base_gas_cost": 1 - }, - "keccak_round_cost_gas_cost": 180000, - "l1_gas": "L1_GAS", - "l1_gas_index": 0, - "l1_handler_version": 0, - "l2_gas": "L2_GAS", - "l2_gas_index": 1, - "library_call_gas_cost": { - "call_contract_gas_cost": 1 - }, - "sha256_process_block_gas_cost": { - "step_gas_cost": 1852, - "range_check_gas_cost": 65, - "bitwise_builtin_gas_cost": 1115, - "syscall_base_gas_cost": 1 - }, - "memory_hole_gas_cost": 10, - "nop_entry_point_offset": -1, - "range_check_gas_cost": 70, - "bitwise_builtin_gas_cost": 594, - "replace_class_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "secp256k1_add_gas_cost": { - "range_check_gas_cost": 29, - "step_gas_cost": 406 - }, - "secp256k1_get_point_from_x_gas_cost": { - "memory_hole_gas_cost": 20, - "range_check_gas_cost": 30, - "step_gas_cost": 391 - }, - "secp256k1_get_xy_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 11, - "step_gas_cost": 239 - }, - "secp256k1_mul_gas_cost": { - "memory_hole_gas_cost": 2, - "range_check_gas_cost": 7045, - "step_gas_cost": 76501 - }, - "secp256k1_new_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 35, - "step_gas_cost": 475 - }, - "secp256r1_add_gas_cost": { - "range_check_gas_cost": 57, - "step_gas_cost": 589 - }, - "secp256r1_get_point_from_x_gas_cost": { - "memory_hole_gas_cost": 20, - "range_check_gas_cost": 44, - "step_gas_cost": 510 - }, - "secp256r1_get_xy_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 11, - "step_gas_cost": 241 - }, - "secp256r1_mul_gas_cost": { - "memory_hole_gas_cost": 2, - "range_check_gas_cost": 13961, - "step_gas_cost": 125340 - }, - "secp256r1_new_gas_cost": { - "memory_hole_gas_cost": 40, - "range_check_gas_cost": 49, - "step_gas_cost": 594 - }, - "send_message_to_l1_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "sierra_array_len_bound": 4294967296, - "step_gas_cost": 100, - "storage_read_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "storage_write_gas_cost": { - "step_gas_cost": 50, - "syscall_base_gas_cost": 1 - }, - "stored_block_hash_buffer": 10, - "syscall_base_gas_cost": { - "step_gas_cost": 100 - }, - "transaction_gas_cost": { - "entry_point_gas_cost": 2, - "fee_transfer_gas_cost": 1, - "step_gas_cost": 100 - }, - "transfer_entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", - "validate_declare_entry_point_selector": "0x289da278a8dc833409cabfdad1581e8e7d40e42dcaed693fa4008dcdb4963b3", - "validate_deploy_entry_point_selector": "0x36fcbf06cd96843058359e1a75928beacfac10727dab22a3972f0af8aa92895", - "validate_entry_point_selector": "0x162da33a4585851fe8d3af3c2a9c60b557814e221e0d4f30ff0b2189d9c7775", - "validate_rounding_consts": { - "validate_block_number_rounding": 100, - "validate_timestamp_rounding": 3600 - }, - "validated": "VALID" - }, - "os_resources": { - "execute_syscalls": { - "CallContract": { - "n_steps": 827, - "builtin_instance_counter": { - "range_check_builtin": 15 - }, - "n_memory_holes": 0 - }, - "DelegateCall": { - "n_steps": 713, - "builtin_instance_counter": { - "range_check_builtin": 19 - }, - "n_memory_holes": 0 - }, - "DelegateL1Handler": { - "n_steps": 692, - "builtin_instance_counter": { - "range_check_builtin": 15 - }, - "n_memory_holes": 0 - }, - "Deploy": { - "n_steps": 1097, - "builtin_instance_counter": { - "pedersen_builtin": 7, - "range_check_builtin": 18 - }, - "n_memory_holes": 0 - }, - "EmitEvent": { - "n_steps": 61, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "GetBlockHash": { - "n_steps": 104, - "builtin_instance_counter": { - "range_check_builtin": 2 - }, - "n_memory_holes": 0 - }, - "GetBlockNumber": { - "n_steps": 40, - "builtin_instance_counter": {}, - "n_memory_holes": 0 - }, - "GetBlockTimestamp": { - "n_steps": 38, - "builtin_instance_counter": {}, - "n_memory_holes": 0 - }, - "GetCallerAddress": { - "n_steps": 64, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "GetContractAddress": { - "n_steps": 64, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "GetExecutionInfo": { - "n_steps": 64, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "GetSequencerAddress": { - "n_steps": 34, - "builtin_instance_counter": {}, - "n_memory_holes": 0 - }, - "GetTxInfo": { - "n_steps": 64, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "GetTxSignature": { - "n_steps": 44, - "builtin_instance_counter": {}, - "n_memory_holes": 0 - }, - "Keccak": { - "n_steps": 381, - "builtin_instance_counter": { - "bitwise_builtin": 6, - "keccak_builtin": 1, - "range_check_builtin": 56 - }, - "n_memory_holes": 0 - }, - "LibraryCall": { - "n_steps": 818, - "builtin_instance_counter": { - "range_check_builtin": 15 - }, - "n_memory_holes": 0 - }, - "LibraryCallL1Handler": { - "n_steps": 659, - "builtin_instance_counter": { - "range_check_builtin": 15 - }, - "n_memory_holes": 0 - }, - "ReplaceClass": { - "n_steps": 98, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "Secp256k1Add": { - "n_steps": 410, - "builtin_instance_counter": { - "range_check_builtin": 29 - }, - "n_memory_holes": 0 - }, - "Secp256k1GetPointFromX": { - "n_steps": 395, - "builtin_instance_counter": { - "range_check_builtin": 30 - }, - "n_memory_holes": 0 - }, - "Secp256k1GetXy": { - "n_steps": 207, - "builtin_instance_counter": { - "range_check_builtin": 11 - }, - "n_memory_holes": 0 - }, - "Secp256k1Mul": { - "n_steps": 76505, - "builtin_instance_counter": { - "range_check_builtin": 7045 - }, - "n_memory_holes": 0 - }, - "Secp256k1New": { - "n_steps": 461, - "builtin_instance_counter": { - "range_check_builtin": 35 - }, - "n_memory_holes": 0 - }, - "Secp256r1Add": { - "n_steps": 593, - "builtin_instance_counter": { - "range_check_builtin": 57 - }, - "n_memory_holes": 0 - }, - "Secp256r1GetPointFromX": { - "n_steps": 514, - "builtin_instance_counter": { - "range_check_builtin": 44 - }, - "n_memory_holes": 0 - }, - "Secp256r1GetXy": { - "n_steps": 209, - "builtin_instance_counter": { - "range_check_builtin": 11 - }, - "n_memory_holes": 0 - }, - "Secp256r1Mul": { - "n_steps": 125344, - "builtin_instance_counter": { - "range_check_builtin": 13961 - }, - "n_memory_holes": 0 - }, - "Secp256r1New": { - "n_steps": 580, - "builtin_instance_counter": { - "range_check_builtin": 49 - }, - "n_memory_holes": 0 - }, - "SendMessageToL1": { - "n_steps": 141, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "Sha256ProcessBlock": { - "n_steps": 1855, - "builtin_instance_counter": { - "range_check_builtin": 65, - "bitwise_builtin": 1115 - }, - "n_memory_holes": 0 - }, - "StorageRead": { - "n_steps": 87, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - }, - "StorageWrite": { - "n_steps": 89, - "builtin_instance_counter": { - "range_check_builtin": 1 - }, - "n_memory_holes": 0 - } - }, - "execute_txs_inner": { - "Declare": { - "deprecated_resources": { - "constant": { - "n_steps": 2973, - "builtin_instance_counter": { - "pedersen_builtin": 16, - "range_check_builtin": 53 - }, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 0, - "builtin_instance_counter": {}, - "n_memory_holes": 0 - } - }, - "resources": { - "constant": { - "n_steps": 3079, - "builtin_instance_counter": { - "pedersen_builtin": 4, - "range_check_builtin": 58, - "poseidon_builtin": 10 - }, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 0, - "builtin_instance_counter": {}, - "n_memory_holes": 0 - } - } - }, - "DeployAccount": { - "deprecated_resources": { - "constant": { - "n_steps": 4015, - "builtin_instance_counter": { - "pedersen_builtin": 23, - "range_check_builtin": 72 - }, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 21, - "builtin_instance_counter": { - "pedersen_builtin": 2 - }, - "n_memory_holes": 0 - } - }, - "resources": { - "constant": { - "n_steps": 4137, - "builtin_instance_counter": { - "pedersen_builtin": 11, - "range_check_builtin": 77, - "poseidon_builtin": 10 - }, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 21, - "builtin_instance_counter": { - "pedersen_builtin": 2 - }, - "n_memory_holes": 0 - } - } - }, - "InvokeFunction": { - "deprecated_resources": { - "constant": { - "n_steps": 3763, - "builtin_instance_counter": { - "pedersen_builtin": 14, - "range_check_builtin": 69 - }, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 8, - "builtin_instance_counter": { - "pedersen_builtin": 1 - }, - "n_memory_holes": 0 - } - }, - "resources": { - "constant": { - "n_steps": 3904, - "builtin_instance_counter": { - "pedersen_builtin": 4, - "range_check_builtin": 74, - "poseidon_builtin": 11 - }, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 8, - "builtin_instance_counter": { - "pedersen_builtin": 1 - }, - "n_memory_holes": 0 - } - } - }, - "L1Handler": { - "deprecated_resources": { - "constant": { - "n_steps": 1233, - "builtin_instance_counter": { - "pedersen_builtin": 11, - "range_check_builtin": 16 - }, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 13, - "builtin_instance_counter": { - "pedersen_builtin": 1 - }, - "n_memory_holes": 0 - } - }, - "resources": { - "constant": { - "n_steps": 0, - "builtin_instance_counter": {}, - "n_memory_holes": 0 - }, - "calldata_factor": { - "n_steps": 13, - "builtin_instance_counter": { - "pedersen_builtin": 1 - }, - "n_memory_holes": 0 - } - } - } - }, - "compute_os_kzg_commitment_info": { - "n_steps": 113, - "builtin_instance_counter": { - "range_check_builtin": 17 - }, - "n_memory_holes": 0 - } - }, - "validate_max_n_steps": 1000000, - "vm_resource_fee_cost": { - "add_mod_builtin": [ - 4, - 100 - ], - "bitwise_builtin": [ - 16, - 100 - ], - "ec_op_builtin": [ - 256, - 100 - ], - "ecdsa_builtin": [ - 512, - 100 - ], - "keccak_builtin": [ - 512, - 100 - ], - "mul_mod_builtin": [ - 4, - 100 - ], - "n_steps": [ - 25, - 10000 - ], - "output_builtin": [ - 0, - 1 - ], - "pedersen_builtin": [ - 8, - 100 - ], - "poseidon_builtin": [ - 8, - 100 - ], - "range_check_builtin": [ - 4, - 100 - ], - "range_check96_builtin": [ - 4, - 100 - ] - } -} diff --git a/vm/trace.go b/vm/trace.go index 24a2195393..4009beadb4 100644 --- a/vm/trace.go +++ b/vm/trace.go @@ -122,8 +122,8 @@ func (t *TransactionTrace) allInvocations() []*FunctionInvocation { }, func(i *FunctionInvocation) bool { return i == nil }) } -func (t *TransactionTrace) TotalExecutionResources() *ExecutionResources { - total := new(ExecutionResources) +func (t *TransactionTrace) TotalComputationResources() ComputationResources { + total := ComputationResources{} for _, invocation := range t.allInvocations() { r := invocation.ExecutionResources total.Pedersen += r.Pedersen @@ -244,6 +244,10 @@ type DataAvailability struct { } type ExecutionResources struct { + L1Gas uint64 `json:"l1_gas"` + L1DataGas uint64 `json:"l1_data_gas"` + L2Gas uint64 `json:"l2_gas"` + ComputationResources DataAvailability *DataAvailability `json:"data_availability,omitempty"` } @@ -260,3 +264,14 @@ func NewDataAvailability(gasConsumed, dataGasConsumed *felt.Felt, mode core.L1DA return da } + +// TODO: add RPC 0.6, 0.7 and 0.8 support +func (r *ExecutionResources) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + ComputationResources + DataAvailability *DataAvailability `json:"data_availability,omitempty"` + }{ + ComputationResources: r.ComputationResources, + DataAvailability: r.DataAvailability, + }) +} diff --git a/vm/trace_test.go b/vm/trace_test.go index 51d9329ac4..ae18bb8505 100644 --- a/vm/trace_test.go +++ b/vm/trace_test.go @@ -212,20 +212,18 @@ func TestTotalExecutionResources(t *testing.T) { for description, test := range tests { t.Run(description, func(t *testing.T) { - require.Equal(t, &vm.ExecutionResources{ - ComputationResources: vm.ComputationResources{ - Steps: resources.Steps * test.multiplier, - MemoryHoles: resources.MemoryHoles * test.multiplier, - Pedersen: resources.Pedersen * test.multiplier, - RangeCheck: resources.RangeCheck * test.multiplier, - Bitwise: resources.Bitwise * test.multiplier, - Ecdsa: resources.Ecdsa * test.multiplier, - EcOp: resources.EcOp * test.multiplier, - Keccak: resources.Keccak * test.multiplier, - Poseidon: resources.Poseidon * test.multiplier, - SegmentArena: resources.SegmentArena * test.multiplier, - }, - }, test.trace.TotalExecutionResources()) + require.Equal(t, vm.ComputationResources{ + Steps: resources.Steps * test.multiplier, + MemoryHoles: resources.MemoryHoles * test.multiplier, + Pedersen: resources.Pedersen * test.multiplier, + RangeCheck: resources.RangeCheck * test.multiplier, + Bitwise: resources.Bitwise * test.multiplier, + Ecdsa: resources.Ecdsa * test.multiplier, + EcOp: resources.EcOp * test.multiplier, + Keccak: resources.Keccak * test.multiplier, + Poseidon: resources.Poseidon * test.multiplier, + SegmentArena: resources.SegmentArena * test.multiplier, + }, test.trace.TotalComputationResources()) }) } } diff --git a/vm/transaction.go b/vm/transaction.go index 97200692c6..f4e63eb29f 100644 --- a/vm/transaction.go +++ b/vm/transaction.go @@ -95,6 +95,7 @@ type Resource uint32 const ( ResourceL1Gas Resource = iota + 1 ResourceL2Gas + ResourceL1DataGas ) func (r Resource) MarshalText() ([]byte, error) { @@ -103,6 +104,8 @@ func (r Resource) MarshalText() ([]byte, error) { return []byte("L1_GAS"), nil case ResourceL2Gas: return []byte("L2_GAS"), nil + case ResourceL1DataGas: + return []byte("L1_DATA"), nil default: return nil, fmt.Errorf("unknown resource %v", r) } diff --git a/vm/vm.go b/vm/vm.go index 6f0f00155a..adc9b92caf 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -1,46 +1,10 @@ package vm /* -#include -#include -#include - -#define FELT_SIZE 32 - -typedef struct CallInfo { - unsigned char contract_address[FELT_SIZE]; - unsigned char class_hash[FELT_SIZE]; - unsigned char entry_point_selector[FELT_SIZE]; - unsigned char** calldata; - size_t len_calldata; -} CallInfo; - -typedef struct BlockInfo { - unsigned long long block_number; - unsigned long long block_timestamp; - unsigned char sequencer_address[FELT_SIZE]; - unsigned char gas_price_wei[FELT_SIZE]; - unsigned char gas_price_fri[FELT_SIZE]; - char* version; - unsigned char block_hash_to_be_revealed[FELT_SIZE]; - unsigned char data_gas_price_wei[FELT_SIZE]; - unsigned char data_gas_price_fri[FELT_SIZE]; - unsigned char use_blob_data; -} BlockInfo; - -extern void cairoVMCall(CallInfo* call_info_ptr, BlockInfo* block_info_ptr, uintptr_t readerHandle, char* chain_id, - unsigned long long max_steps, unsigned char concurrency_mode); - -extern void cairoVMExecute(char* txns_json, char* classes_json, char* paid_fees_on_l1_json, - BlockInfo* block_info_ptr, uintptr_t readerHandle, char* chain_id, - unsigned char skip_charge_fee, unsigned char skip_validate, unsigned char err_on_revert, - unsigned char concurrency_mode); - -extern char* setVersionedConstants(char* json); -extern void freeString(char* str); - #cgo vm_debug LDFLAGS: -L./rust/target/debug -ljuno_starknet_rs -lbz2 #cgo !vm_debug LDFLAGS: -L./rust/target/release -ljuno_starknet_rs -lbz2 + +#include "vm_ffi.h" */ import "C" @@ -59,13 +23,21 @@ import ( "github.com/NethermindEth/juno/utils" ) +type ExecutionResults struct { + OverallFees []*felt.Felt + DataAvailability []core.DataAvailability + GasConsumed []core.GasConsumed + Traces []TransactionTrace + NumSteps uint64 +} + //go:generate mockgen -destination=../mocks/mock_vm.go -package=mocks github.com/NethermindEth/juno/vm VM type VM interface { Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateReader, network *utils.Network, - maxSteps uint64) ([]*felt.Felt, error) + maxSteps uint64, sierraVersion string) ([]*felt.Felt, error) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool, - ) ([]*felt.Felt, []core.GasConsumed, []TransactionTrace, uint64, error) + ) (ExecutionResults, error) } type vm struct { @@ -94,7 +66,8 @@ type callContext struct { // fee amount taken per transaction during VM execution actualFees []*felt.Felt traces []json.RawMessage - daGas []core.GasConsumed + daGas []core.DataAvailability + gasConsumed []core.GasConsumed executionSteps uint64 } @@ -133,12 +106,22 @@ func JunoAppendActualFee(readerHandle C.uintptr_t, ptr unsafe.Pointer) { context.actualFees = append(context.actualFees, makeFeltFromPtr(ptr)) } +//export JunoAppendDAGas +func JunoAppendDAGas(readerHandle C.uintptr_t, ptr, ptr2 unsafe.Pointer) { + context := unwrapContext(readerHandle) + context.daGas = append(context.daGas, core.DataAvailability{ + L1Gas: makeFeltFromPtr(ptr).Uint64(), + L1DataGas: makeFeltFromPtr(ptr2).Uint64(), + }) +} + //export JunoAppendGasConsumed -func JunoAppendGasConsumed(readerHandle C.uintptr_t, ptr, ptr2 unsafe.Pointer) { +func JunoAppendGasConsumed(readerHandle C.uintptr_t, ptr, ptr2, ptr3 unsafe.Pointer) { context := unwrapContext(readerHandle) - context.daGas = append(context.daGas, core.GasConsumed{ + context.gasConsumed = append(context.gasConsumed, core.GasConsumed{ L1Gas: makeFeltFromPtr(ptr).Uint64(), L1DataGas: makeFeltFromPtr(ptr2).Uint64(), + L2Gas: makeFeltFromPtr(ptr3).Uint64(), }) } @@ -206,20 +189,24 @@ func makeCBlockInfo(blockInfo *BlockInfo) C.BlockInfo { cBlockInfo.block_number = C.ulonglong(blockInfo.Header.Number) cBlockInfo.block_timestamp = C.ulonglong(blockInfo.Header.Timestamp) copyFeltIntoCArray(blockInfo.Header.SequencerAddress, &cBlockInfo.sequencer_address[0]) - copyFeltIntoCArray(blockInfo.Header.L1GasPriceETH, &cBlockInfo.gas_price_wei[0]) - copyFeltIntoCArray(blockInfo.Header.L1GasPriceSTRK, &cBlockInfo.gas_price_fri[0]) + copyFeltIntoCArray(blockInfo.Header.L1GasPriceETH, &cBlockInfo.l1_gas_price_wei[0]) + copyFeltIntoCArray(blockInfo.Header.L1GasPriceSTRK, &cBlockInfo.l1_gas_price_fri[0]) cBlockInfo.version = cstring([]byte(blockInfo.Header.ProtocolVersion)) copyFeltIntoCArray(blockInfo.BlockHashToBeRevealed, &cBlockInfo.block_hash_to_be_revealed[0]) if blockInfo.Header.L1DAMode == core.Blob { - copyFeltIntoCArray(blockInfo.Header.L1DataGasPrice.PriceInWei, &cBlockInfo.data_gas_price_wei[0]) - copyFeltIntoCArray(blockInfo.Header.L1DataGasPrice.PriceInFri, &cBlockInfo.data_gas_price_fri[0]) + copyFeltIntoCArray(blockInfo.Header.L1DataGasPrice.PriceInWei, &cBlockInfo.l1_data_gas_price_wei[0]) + copyFeltIntoCArray(blockInfo.Header.L1DataGasPrice.PriceInFri, &cBlockInfo.l1_data_gas_price_fri[0]) cBlockInfo.use_blob_data = 1 } + if blockInfo.Header.L2GasPrice != nil { + copyFeltIntoCArray(blockInfo.Header.L2GasPrice.PriceInWei, &cBlockInfo.l2_gas_price_wei[0]) + copyFeltIntoCArray(blockInfo.Header.L2GasPrice.PriceInFri, &cBlockInfo.l2_gas_price_fri[0]) + } return cBlockInfo } func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateReader, - network *utils.Network, maxSteps uint64, + network *utils.Network, maxSteps uint64, sierraVersion string, ) ([]*felt.Felt, error) { context := &callContext{ state: state, @@ -238,6 +225,7 @@ func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateRead cCallInfo, callInfoPinner := makeCCallInfo(callInfo) cBlockInfo := makeCBlockInfo(blockInfo) chainID := C.CString(network.L2ChainID) + cSierraVersion := C.CString(sierraVersion) C.cairoVMCall( &cCallInfo, &cBlockInfo, @@ -245,10 +233,12 @@ func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateRead chainID, C.ulonglong(maxSteps), //nolint:gocritic C.uchar(concurrencyModeByte), //nolint:gocritic + cSierraVersion, //nolint:gocritic ) callInfoPinner.Unpin() C.free(unsafe.Pointer(chainID)) C.free(unsafe.Pointer(cBlockInfo.version)) + C.free(unsafe.Pointer(cSierraVersion)) if context.err != "" { return nil, errors.New(context.err) @@ -260,7 +250,7 @@ func (v *vm) Call(callInfo *CallInfo, blockInfo *BlockInfo, state core.StateRead func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, paidFeesOnL1 []*felt.Felt, blockInfo *BlockInfo, state core.StateReader, network *utils.Network, skipChargeFee, skipValidate, errOnRevert bool, -) ([]*felt.Felt, []core.GasConsumed, []TransactionTrace, uint64, error) { +) (ExecutionResults, error) { context := &callContext{ state: state, log: v.log, @@ -270,12 +260,12 @@ func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, paid txnsJSON, classesJSON, err := marshalTxnsAndDeclaredClasses(txns, declaredClasses) if err != nil { - return nil, nil, nil, 0, err + return ExecutionResults{}, err } paidFeesOnL1Bytes, err := json.Marshal(paidFeesOnL1) if err != nil { - return nil, nil, nil, 0, err + return ExecutionResults{}, err } paidFeesOnL1CStr := cstring(paidFeesOnL1Bytes) @@ -324,21 +314,27 @@ func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, paid if context.err != "" { if context.errTxnIndex >= 0 { - return nil, nil, nil, 0, TransactionExecutionError{ + return ExecutionResults{}, TransactionExecutionError{ Index: uint64(context.errTxnIndex), Cause: errors.New(context.err), } } - return nil, nil, nil, 0, errors.New(context.err) + return ExecutionResults{}, errors.New(context.err) } traces := make([]TransactionTrace, len(context.traces)) for index, traceJSON := range context.traces { if err := json.Unmarshal(traceJSON, &traces[index]); err != nil { - return nil, nil, nil, 0, fmt.Errorf("unmarshal trace: %v", err) + return ExecutionResults{}, fmt.Errorf("unmarshal trace: %v", err) } } - return context.actualFees, context.daGas, traces, context.executionSteps, nil + return ExecutionResults{ + OverallFees: context.actualFees, + DataAvailability: context.daGas, + GasConsumed: context.gasConsumed, + Traces: traces, + NumSteps: context.executionSteps, + }, nil } func marshalTxnsAndDeclaredClasses(txns []core.Transaction, declaredClasses []core.Class) (json.RawMessage, json.RawMessage, error) { diff --git a/vm/vm_ffi.h b/vm/vm_ffi.h new file mode 100644 index 0000000000..df3c8b3b8a --- /dev/null +++ b/vm/vm_ffi.h @@ -0,0 +1,45 @@ +#ifndef VM_FFI_H +#define VM_FFI_H + +#include +#include +#include + +#define FELT_SIZE 32 + +typedef struct CallInfo { + unsigned char contract_address[FELT_SIZE]; + unsigned char class_hash[FELT_SIZE]; + unsigned char entry_point_selector[FELT_SIZE]; + unsigned char** calldata; + size_t len_calldata; +} CallInfo; + +typedef struct BlockInfo { + unsigned long long block_number; + unsigned long long block_timestamp; + unsigned char sequencer_address[FELT_SIZE]; + unsigned char l1_gas_price_wei[FELT_SIZE]; + unsigned char l1_gas_price_fri[FELT_SIZE]; + char* version; + unsigned char block_hash_to_be_revealed[FELT_SIZE]; + unsigned char l1_data_gas_price_wei[FELT_SIZE]; + unsigned char l1_data_gas_price_fri[FELT_SIZE]; + unsigned char use_blob_data; + unsigned char l2_gas_price_wei[FELT_SIZE]; + unsigned char l2_gas_price_fri[FELT_SIZE]; +} BlockInfo; + +extern void cairoVMCall(CallInfo* call_info_ptr, BlockInfo* block_info_ptr, uintptr_t readerHandle, char* chain_id, + unsigned long long max_steps, unsigned char concurrency_mode, char* sierra_version); + +extern void cairoVMExecute(char* txns_json, char* classes_json, char* paid_fees_on_l1_json, + BlockInfo* block_info_ptr, uintptr_t readerHandle, char* chain_id, + unsigned char skip_charge_fee, unsigned char skip_validate, unsigned char err_on_revert, + unsigned char concurrency_mode); + +extern char* setVersionedConstants(char* json); +extern void freeString(char* str); + +#endif // VM_FFI_H + diff --git a/vm/vm_test.go b/vm/vm_test.go index a32ada4468..e80155d47c 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -50,7 +50,7 @@ func TestV0Call(t *testing.T) { ContractAddress: contractAddr, ClassHash: classHash, Selector: entryPoint, - }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 1_000_000) + }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 1_000_000, "") require.NoError(t, err) assert.Equal(t, []*felt.Felt{&felt.Zero}, ret) @@ -70,7 +70,7 @@ func TestV0Call(t *testing.T) { ContractAddress: contractAddr, ClassHash: classHash, Selector: entryPoint, - }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Mainnet, 1_000_000) + }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Mainnet, 1_000_000, "") require.NoError(t, err) assert.Equal(t, []*felt.Felt{new(felt.Felt).SetUint64(1337)}, ret) } @@ -117,7 +117,7 @@ func TestV1Call(t *testing.T) { Calldata: []felt.Felt{ *storageLocation, }, - }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Goerli, 1_000_000) + }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Goerli, 1_000_000, "") require.NoError(t, err) assert.Equal(t, []*felt.Felt{&felt.Zero}, ret) @@ -139,7 +139,7 @@ func TestV1Call(t *testing.T) { Calldata: []felt.Felt{ *storageLocation, }, - }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Goerli, 1_000_000) + }, &BlockInfo{Header: &core.Header{Number: 1}}, testState, &utils.Goerli, 1_000_000, "") require.NoError(t, err) assert.Equal(t, []*felt.Felt{new(felt.Felt).SetUint64(37)}, ret) } @@ -179,7 +179,7 @@ func TestCall_MaxSteps(t *testing.T) { ContractAddress: contractAddr, ClassHash: classHash, Selector: entryPoint, - }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 0) + }, &BlockInfo{Header: &core.Header{}}, testState, &utils.Mainnet, 0, "") assert.ErrorContains(t, err, "RunResources has no remaining steps") } @@ -196,7 +196,7 @@ func TestExecute(t *testing.T) { state := core.NewState(txn) t.Run("empty transaction list", func(t *testing.T) { - _, _, _, _, err := New(false, nil).Execute([]core.Transaction{}, []core.Class{}, []*felt.Felt{}, &BlockInfo{ + _, err := New(false, nil).Execute([]core.Transaction{}, []core.Class{}, []*felt.Felt{}, &BlockInfo{ Header: &core.Header{ Timestamp: 1666877926, SequencerAddress: utils.HexToFelt(t, "0x46a89ae102987331d369645031b49c27738ed096f2789c24449966da4c6de6b"), @@ -208,7 +208,7 @@ func TestExecute(t *testing.T) { require.NoError(t, err) }) t.Run("zero data", func(t *testing.T) { - _, _, _, _, err := New(false, nil).Execute(nil, nil, []*felt.Felt{}, &BlockInfo{ + _, err := New(false, nil).Execute(nil, nil, []*felt.Felt{}, &BlockInfo{ Header: &core.Header{ SequencerAddress: &felt.Zero, L1GasPriceETH: &felt.Zero, @@ -220,10 +220,16 @@ func TestExecute(t *testing.T) { } func TestSetVersionedConstants(t *testing.T) { - t.Run("ok", func(t *testing.T) { - err := SetVersionedConstants("./rust/versioned_constants_13_1.json") - assert.NoError(t, err) - }) + path := "rust/resources/" + f, err := os.Open(path) + require.NoError(t, err) + files, err := f.Readdir(0) + require.NoError(t, err) + + for _, v := range files { + require.NoError(t, SetVersionedConstants(path+v.Name())) + } + t.Run("not valid json", func(t *testing.T) { fd, err := os.CreateTemp(t.TempDir(), "versioned_constants_test*") require.NoError(t, err)