@@ -16,6 +16,10 @@ import (
1616 "testing"
1717 "time"
1818
19+ "github.com/cartesi/rollups-node/internal/model"
20+ "github.com/cartesi/rollups-node/internal/repository"
21+ "github.com/cartesi/rollups-node/pkg/contracts/inputs"
22+ "github.com/cartesi/rollups-node/pkg/contracts/outputs"
1923 "github.com/cartesi/rollups-node/pkg/service"
2024 "github.com/stretchr/testify/require"
2125)
@@ -247,6 +251,123 @@ func TestJSONRPCBatchReplacesResponsesAtCumulativeResponseBudget(t *testing.T) {
247251 }
248252}
249253
254+ func TestJSONRPCBatchSharesListItemLimitAcrossAllListOperations (t * testing.T ) {
255+ s := newBatchTestService ()
256+ repo := & listBudgetRepository {}
257+ s .repository = repo
258+ var err error
259+ s .inputABI , err = inputs .InputsMetaData .GetAbi ()
260+ require .NoError (t , err )
261+ s .outputABI , err = outputs .OutputsMetaData .GetAbi ()
262+ require .NoError (t , err )
263+ expected := []struct {limit int ; count int }{
264+ {1000 , 1000 },
265+ {2000 , 2000 },
266+ {3000 , 3000 },
267+ {LIST_ITEM_LIMIT , LIST_ITEM_LIMIT - 6000 },
268+ {4000 , 0 },
269+ {5000 , 0 },
270+ {6000 , 0 },
271+ {7000 , 0 },
272+ {8000 , 0 },
273+ {9000 , 0 },
274+ }
275+ requests := []map [string ]any {
276+ {"jsonrpc" : "2.0" , "method" : "cartesi_listApplications" , "params" : map [string ]any {"limit" : expected [0 ].limit }, "id" : 0 },
277+ {"jsonrpc" : "2.0" , "method" : "cartesi_listEpochs" , "params" : listBudgetParams (expected [1 ].limit ), "id" : 1 },
278+ {"jsonrpc" : "2.0" , "method" : "cartesi_listInputs" , "params" : listBudgetParams (expected [2 ].limit ), "id" : 2 },
279+ {"jsonrpc" : "2.0" , "method" : "cartesi_listOutputs" , "params" : listBudgetParams (expected [3 ].limit ), "id" : 3 },
280+ {"jsonrpc" : "2.0" , "method" : "cartesi_listReports" , "params" : listBudgetParams (expected [4 ].limit ), "id" : 4 },
281+ {"jsonrpc" : "2.0" , "method" : "cartesi_listWithdrawals" , "params" : listBudgetParams (expected [5 ].limit ), "id" : 5 },
282+ {"jsonrpc" : "2.0" , "method" : "cartesi_listTournaments" , "params" : listBudgetParams (expected [6 ].limit ), "id" : 6 },
283+ {"jsonrpc" : "2.0" , "method" : "cartesi_listCommitments" , "params" : listBudgetParams (expected [7 ].limit ), "id" : 7 },
284+ {"jsonrpc" : "2.0" , "method" : "cartesi_listMatches" , "params" : listBudgetParams (expected [8 ].limit ), "id" : 8 },
285+ {"jsonrpc" : "2.0" , "method" : "cartesi_listMatchAdvances" , "params" : listMatchAdvancesBudgetParams (expected [9 ].limit ), "id" : 9 },
286+ }
287+ body , err := json .Marshal (requests )
288+ require .NoError (t , err )
289+ rr := serveRPC (t , s , body )
290+
291+ require .Equal (t , http .StatusOK , rr .Code )
292+ responses := decodeRPCBatch (t , rr .Body .Bytes ())
293+ require .Len (t , responses , len (requests ))
294+ for i , response := range responses {
295+ require .Nil (t , response .Error , "list operation %s failed" , requests [i ]["method" ])
296+ result := response .Result .(map [string ]any )
297+ require .Equal (t , expected [i ].count , len (result ["data" ].([]any )))
298+ require .Equal (t , float64 (LIST_ITEM_LIMIT ), result ["pagination" ].(map [string ]any )["total_count" ])
299+ require .Equal (t , float64 (i ), response .ID )
300+ }
301+ }
302+
303+ func listBudgetParams (limit int ) map [string ]any {
304+ return map [string ]any {"application" : "app" , "limit" : limit }
305+ }
306+
307+ func listMatchAdvancesBudgetParams (limit int ) map [string ]any {
308+ params := listBudgetParams (limit )
309+ params ["epoch_index" ] = "0x0"
310+ params ["tournament_address" ] = "0x0000000000000000000000000000000000000000"
311+ params ["id_hash" ] = "0x0000000000000000000000000000000000000000000000000000000000000000"
312+ return params
313+ }
314+
315+ type listBudgetRepository struct {
316+ repository.Repository
317+ }
318+
319+ func (r * listBudgetRepository ) GetApplication (_ context.Context , _ string ) (* model.Application , error ) {
320+ return & model.Application {}, nil
321+ }
322+
323+ func (r * listBudgetRepository ) ListApplications (_ context.Context , _ repository.ApplicationFilter , p repository.Pagination , _ bool ) ([]* model.Application , uint64 , error ) {
324+ return make ([]* model.Application , p .Limit ), LIST_ITEM_LIMIT , nil
325+ }
326+
327+ func (r * listBudgetRepository ) ListEpochs (_ context.Context , _ string , _ repository.EpochFilter , p repository.Pagination , _ bool ) ([]* model.Epoch , uint64 , error ) {
328+ return make ([]* model.Epoch , p .Limit ), LIST_ITEM_LIMIT , nil
329+ }
330+
331+ func (r * listBudgetRepository ) ListInputs (_ context.Context , _ string , _ repository.InputFilter , p repository.Pagination , _ bool ) ([]* model.Input , uint64 , error ) {
332+ inputs := make ([]* model.Input , p .Limit )
333+ for i := range inputs {
334+ inputs [i ] = & model.Input {RawData : []byte {0xAA , 0xBB , 0xCC , 0xDD , 0xEE , 0xFF }}
335+ }
336+ return inputs , LIST_ITEM_LIMIT , nil
337+ }
338+
339+ func (r * listBudgetRepository ) ListOutputs (_ context.Context , _ string , _ repository.OutputFilter , p repository.Pagination , _ bool ) ([]* model.Output , uint64 , error ) {
340+ outputs := make ([]* model.Output , p .Limit )
341+ for i := range outputs {
342+ outputs [i ] = & model.Output {RawData : []byte {0xAA , 0xBB , 0xCC , 0xDD , 0xEE , 0xFF }}
343+ }
344+ return outputs , LIST_ITEM_LIMIT , nil
345+ }
346+
347+ func (r * listBudgetRepository ) ListReports (_ context.Context , _ string , _ repository.ReportFilter , p repository.Pagination , _ bool ) ([]* model.Report , uint64 , error ) {
348+ return make ([]* model.Report , p .Limit ), LIST_ITEM_LIMIT , nil
349+ }
350+
351+ func (r * listBudgetRepository ) ListWithdrawals (_ context.Context , _ string , _ repository.WithdrawalFilter , p repository.Pagination , _ bool ) ([]* model.Withdrawal , uint64 , error ) {
352+ return make ([]* model.Withdrawal , p .Limit ), LIST_ITEM_LIMIT , nil
353+ }
354+
355+ func (r * listBudgetRepository ) ListTournaments (_ context.Context , _ string , _ repository.TournamentFilter , p repository.Pagination , _ bool ) ([]* model.Tournament , uint64 , error ) {
356+ return make ([]* model.Tournament , p .Limit ), LIST_ITEM_LIMIT , nil
357+ }
358+
359+ func (r * listBudgetRepository ) ListCommitments (_ context.Context , _ string , _ repository.CommitmentFilter , p repository.Pagination , _ bool ) ([]* model.Commitment , uint64 , error ) {
360+ return make ([]* model.Commitment , p .Limit ), LIST_ITEM_LIMIT , nil
361+ }
362+
363+ func (r * listBudgetRepository ) ListMatches (_ context.Context , _ string , _ repository.MatchFilter , p repository.Pagination , _ bool ) ([]* model.Match , uint64 , error ) {
364+ return make ([]* model.Match , p .Limit ), LIST_ITEM_LIMIT , nil
365+ }
366+
367+ func (r * listBudgetRepository ) ListMatchAdvances (_ context.Context , _ string , _ uint64 , _ , _ string , p repository.Pagination , _ bool ) ([]* model.MatchAdvanced , uint64 , error ) {
368+ return make ([]* model.MatchAdvanced , p .Limit ), LIST_ITEM_LIMIT , nil
369+ }
370+
250371func TestJSONRPCBatchStopsBetweenEntriesWhenContextIsCanceled (t * testing.T ) {
251372 s := newBatchTestService ()
252373 var calls atomic.Int32
0 commit comments