From cf05857803cd7a6b5675d853c153fd0be365a56b Mon Sep 17 00:00:00 2001 From: weiihann Date: Sat, 1 Mar 2025 15:27:56 +0800 Subject: [PATCH] fix(rpc): failed fee estimation due to absence of l1_data_gas add dummy test for code coverage --- adapters/sn2core/sn2core.go | 15 +++++++++++++++ core/transaction.go | 4 ++++ rpc/v7/simulation_test.go | 28 ++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/adapters/sn2core/sn2core.go b/adapters/sn2core/sn2core.go index dd3e54e602..4654aada47 100644 --- a/adapters/sn2core/sn2core.go +++ b/adapters/sn2core/sn2core.go @@ -199,6 +199,21 @@ func adaptResourceBounds(rb *map[starknet.Resource]starknet.ResourceBounds) map[ MaxPricePerUnit: bounds.MaxPricePerUnit, } } + + // Ensures that the L1DataGas resource is always present if L2Gas is non-zero. + // In RPC v8, L1Gas, L2Gas and L1DataGas are part of the spec and required. + // In RPC v6 and v7, only L1Gas and L2Gas are part of the spec and required. + // Blockifier will throw an error if L1DataGas is absent and L2Gas is non-zero. + // To avoid that, if L2Gas is non-zero, we set the L1DataGas resource to zero. + if l2Gas, ok := coreBounds[core.ResourceL2Gas]; ok && !l2Gas.IsZero() { + if _, ok := coreBounds[core.ResourceL1DataGas]; !ok { + coreBounds[core.ResourceL1DataGas] = core.ResourceBounds{ + MaxAmount: 0, + MaxPricePerUnit: &felt.Zero, + } + } + } + return coreBounds } diff --git a/core/transaction.go b/core/transaction.go index c65bc0d205..7d3b1e0917 100644 --- a/core/transaction.go +++ b/core/transaction.go @@ -74,6 +74,10 @@ func (rb ResourceBounds) Bytes(resource Resource) []byte { ) } +func (rb ResourceBounds) IsZero() bool { + return rb.MaxAmount == 0 && (rb.MaxPricePerUnit == nil || rb.MaxPricePerUnit.IsZero()) +} + type Event struct { Data []*felt.Felt From *felt.Felt diff --git a/rpc/v7/simulation_test.go b/rpc/v7/simulation_test.go index 0e002c2199..5470080eea 100644 --- a/rpc/v7/simulation_test.go +++ b/rpc/v7/simulation_test.go @@ -69,6 +69,34 @@ func TestSimulateTransactions(t *testing.T) { assert.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "123") }) + t.Run("ok with l2gas present", func(t *testing.T) { + stepsUsed := uint64(123) + mockVM.EXPECT().Execute([]core.Transaction{}, nil, []*felt.Felt{}, &vm.BlockInfo{ + Header: headsHeader, + }, mockState, n, false, true, false, false). + Return(vm.ExecutionResults{ + OverallFees: []*felt.Felt{}, + DataAvailability: []core.DataAvailability{}, + Traces: []vm.TransactionTrace{}, + NumSteps: stepsUsed, + }, nil) + + txn := rpcv7.BroadcastedTransaction{ + Transaction: rpcv7.Transaction{ + ResourceBounds: &map[rpcv7.Resource]rpcv7.ResourceBounds{ + rpcv7.Resource(core.ResourceL2Gas): { + MaxAmount: new(felt.Felt).SetUint64(100), + MaxPricePerUnit: new(felt.Felt).SetUint64(100), + }, + }, + }, + } + + _, httpHeader, err := handler.SimulateTransactions(rpcv7.BlockID{Latest: true}, []rpcv7.BroadcastedTransaction{txn}, []rpcv7.SimulationFlag{rpcv7.SkipValidateFlag}) + require.Nil(t, err) + assert.Equal(t, httpHeader.Get(rpcv7.ExecutionStepsHeader), "123") + }) + 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{