@@ -302,6 +302,90 @@ func TestGRPCQueryLedgerRecords(t *testing.T) {
302302 }
303303}
304304
305+ func TestGRPCQueryLedgerRecordsReverse (t * testing.T ) {
306+ suite := setupTest (t )
307+ _ = seedLedgerRecords (t , suite .ctx , suite .keeper )
308+
309+ ctx := suite .ctx
310+
311+ t .Run ("reverse returns records in opposite order of forward" , func (t * testing.T ) {
312+ // Get forward order
313+ fwd , err := suite .queryClient .LedgerRecords (ctx , & types.QueryLedgerRecordsRequest {})
314+ require .NoError (t , err )
315+
316+ // Get reverse order
317+ rev , err := suite .queryClient .LedgerRecords (ctx , & types.QueryLedgerRecordsRequest {
318+ Pagination : & sdkquery.PageRequest {Reverse : true },
319+ })
320+ require .NoError (t , err )
321+ require .Len (t , rev .Records , len (fwd .Records ))
322+
323+ // Reverse should be the exact opposite of forward
324+ for i := range fwd .Records {
325+ j := len (fwd .Records ) - 1 - i
326+ require .Equal (t , fwd .Records [i ].ID , rev .Records [j ].ID ,
327+ "reverse[%d] should equal forward[%d]" , j , i )
328+ }
329+ })
330+
331+ t .Run ("reverse with pagination key (multi-page)" , func (t * testing.T ) {
332+ // Get all records in reverse for reference
333+ allRev , err := suite .queryClient .LedgerRecords (ctx , & types.QueryLedgerRecordsRequest {
334+ Pagination : & sdkquery.PageRequest {Reverse : true },
335+ })
336+ require .NoError (t , err )
337+
338+ // First page: 2 records
339+ res1 , err := suite .queryClient .LedgerRecords (ctx , & types.QueryLedgerRecordsRequest {
340+ Pagination : & sdkquery.PageRequest {Limit : 2 , Reverse : true },
341+ })
342+ require .NoError (t , err )
343+ require .Len (t , res1 .Records , 2 )
344+ require .NotEmpty (t , res1 .Pagination .NextKey )
345+
346+ // Second page — Reverse is NOT set; it's encoded in the NextKey
347+ res2 , err := suite .queryClient .LedgerRecords (ctx , & types.QueryLedgerRecordsRequest {
348+ Pagination : & sdkquery.PageRequest {Key : res1 .Pagination .NextKey , Limit : 10 },
349+ })
350+ require .NoError (t , err )
351+ require .Len (t , res2 .Records , 2 )
352+
353+ // Paginated results should match full reverse query
354+ paginated := append (res1 .Records , res2 .Records ... )
355+ require .Len (t , paginated , len (allRev .Records ))
356+ for i := range paginated {
357+ require .Equal (t , allRev .Records [i ].ID , paginated [i ].ID ,
358+ "paginated[%d] should match full reverse[%d]" , i , i )
359+ }
360+ })
361+
362+ t .Run ("reverse with status filter" , func (t * testing.T ) {
363+ // Get forward with status filter
364+ fwd , err := suite .queryClient .LedgerRecords (ctx , & types.QueryLedgerRecordsRequest {
365+ Filters : types.LedgerRecordFilters {
366+ Status : "ledger_record_status_pending" ,
367+ },
368+ Pagination : & sdkquery.PageRequest {},
369+ })
370+ require .NoError (t , err )
371+ require .Len (t , fwd .Records , 2 )
372+
373+ // Get reverse with same status filter
374+ rev , err := suite .queryClient .LedgerRecords (ctx , & types.QueryLedgerRecordsRequest {
375+ Filters : types.LedgerRecordFilters {
376+ Status : "ledger_record_status_pending" ,
377+ },
378+ Pagination : & sdkquery.PageRequest {Reverse : true },
379+ })
380+ require .NoError (t , err )
381+ require .Len (t , rev .Records , 2 )
382+
383+ // Should be opposite order
384+ require .Equal (t , fwd .Records [0 ].ID , rev .Records [1 ].ID )
385+ require .Equal (t , fwd .Records [1 ].ID , rev .Records [0 ].ID )
386+ })
387+ }
388+
305389type ledgerFilterModifier struct {
306390 fieldName string
307391 f func (id types.LedgerRecordID , filter types.LedgerRecordFilters ) types.LedgerRecordFilters
0 commit comments