@@ -2,11 +2,13 @@ package loopd
22
33import (
44 "bytes"
5+ "cmp"
56 "context"
67 "encoding/hex"
78 "errors"
89 "fmt"
910 "reflect"
11+ "slices"
1012 "sort"
1113 "strings"
1214 "sync"
@@ -563,8 +565,11 @@ func (s *swapClientServer) ListSwaps(ctx context.Context,
563565 req * looprpc.ListSwapsRequest ) (* looprpc.ListSwapsResponse , error ) {
564566
565567 var (
566- rpcSwaps = []* looprpc.SwapStatus {}
567- idx = 0
568+ rpcSwaps = []* looprpc.SwapStatus {}
569+ swapInfos = []* loop.SwapInfo {}
570+ maxSwaps = int (req .MaxSwaps )
571+ nextStartTime = int64 (0 )
572+ canPage = false
568573 )
569574
570575 s .swapsLock .Lock ()
@@ -580,14 +585,43 @@ func (s *swapClientServer) ListSwaps(ctx context.Context,
580585 continue
581586 }
582587
583- rpcSwap , err := s .marshallSwap (ctx , & swp )
588+ swapInfos = append (swapInfos , & swp )
589+ }
590+
591+ // Sort the swaps by initiation time in ascending order (oldest first).
592+ slices .SortFunc (swapInfos , func (a , b * loop.SwapInfo ) int {
593+ return cmp .Compare (
594+ a .InitiationTime .UnixNano (),
595+ b .InitiationTime .UnixNano (),
596+ )
597+ })
598+
599+ // Apply the maxSwaps limit if specified.
600+ if maxSwaps > 0 && len (swapInfos ) > maxSwaps {
601+ canPage = true
602+ swapInfos = swapInfos [:maxSwaps ]
603+ }
604+
605+ // Marshal the filtered and limited swaps.
606+ for _ , swp := range swapInfos {
607+ rpcSwap , err := s .marshallSwap (ctx , swp )
584608 if err != nil {
585609 return nil , err
586610 }
587611 rpcSwaps = append (rpcSwaps , rpcSwap )
588- idx ++
589612 }
590- return & looprpc.ListSwapsResponse {Swaps : rpcSwaps }, nil
613+
614+ // Set the next start time for pagination if needed.
615+ if canPage && len (rpcSwaps ) > 0 {
616+ // Use the initiation time of the last swap plus 1 nanosecond.
617+ nextStartTime = rpcSwaps [len (rpcSwaps )- 1 ].InitiationTime + 1
618+ }
619+
620+ response := looprpc.ListSwapsResponse {
621+ Swaps : rpcSwaps ,
622+ NextStartTime : nextStartTime ,
623+ }
624+ return & response , nil
591625}
592626
593627// filterSwap filters the given swap based on the provided filter.
@@ -617,6 +651,13 @@ func filterSwap(swapInfo *loop.SwapInfo, filter *looprpc.ListSwapsFilter) bool {
617651 return false
618652 }
619653
654+ // If timestamp filters are set, only return swaps within the specified time range.
655+ if filter .StartTimestampNs > 0 &&
656+ swapInfo .InitiationTime .UnixNano () < filter .StartTimestampNs {
657+
658+ return false
659+ }
660+
620661 // If the swap is of type loop out and the outgoing channel filter is
621662 // set, we only return swaps that match the filter.
622663 if swapInfo .SwapType == swap .TypeOut && filter .OutgoingChanSet != nil {
0 commit comments