Skip to content

Commit 8b758d1

Browse files
committed
looprpc: add simple pagination to the ListSwaps command
This commit adds the ability to set a max_swaps and an index_offset flag to the ListSwaps command. These new fields are applied AFTER the initial filtering step. The response also now passes additional information about the index count and total swaps filtered.
1 parent bfe7991 commit 8b758d1

File tree

5 files changed

+1020
-864
lines changed

5 files changed

+1020
-864
lines changed

cmd/loop/swaps.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ var listSwapsCommand = cli.Command{
3535
labelFlag,
3636
channelFlag,
3737
lastHopFlag,
38+
cli.Uint64Flag{
39+
Name: "max_swaps",
40+
Usage: "Max number of swaps to return after filtering",
41+
},
42+
cli.Uint64Flag{
43+
Name: "index_offset",
44+
Usage: "index to start listing filtered swaps from",
45+
},
3846
},
3947
}
4048

@@ -102,6 +110,8 @@ func listSwaps(ctx *cli.Context) error {
102110
resp, err := client.ListSwaps(
103111
context.Background(), &looprpc.ListSwapsRequest{
104112
ListSwapFilter: filter,
113+
IndexOffset: uint32(ctx.Uint("index_offset")),
114+
MaxSwaps: uint32(ctx.Uint("max_swaps")),
105115
},
106116
)
107117
if err != nil {

loopd/swapclient_server.go

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"errors"
88
"fmt"
99
"reflect"
10+
"slices"
1011
"sort"
1112
"strings"
1213
"sync"
@@ -565,29 +566,64 @@ func (s *swapClientServer) ListSwaps(ctx context.Context,
565566
var (
566567
rpcSwaps = []*looprpc.SwapStatus{}
567568
idx = 0
569+
lastIdx = 0
570+
maxSwaps = int(req.MaxSwaps)
568571
)
569572

570573
s.swapsLock.Lock()
571574
defer s.swapsLock.Unlock()
572575

576+
// Convert the swaps map into a slice which can be ordered.
577+
var swapList []loop.SwapInfo
578+
for _, swp := range s.swaps {
579+
swapList = append(swapList, swp)
580+
}
581+
582+
// Sort all swaps by a consistent field, InitiationTime.
583+
slices.SortFunc(swapList, func(a, b loop.SwapInfo) int {
584+
// For descending order (newest first)
585+
if a.InitiationTime.UnixNano() > b.InitiationTime.UnixNano() {
586+
return -1
587+
}
588+
if a.InitiationTime.UnixNano() < b.InitiationTime.UnixNano() {
589+
return 1
590+
}
591+
return 0
592+
})
573593
// We can just use the server's in-memory cache as that contains the
574594
// most up-to-date state including temporary failures which aren't
575595
// persisted to disk. The swaps field is a map, that's why we need an
576596
// additional index.
577-
for _, swp := range s.swaps {
597+
for _, swp := range swapList {
578598
// Filter the swap based on the provided filter.
579599
if !filterSwap(&swp, req.ListSwapFilter) {
580600
continue
581601
}
582602

583-
rpcSwap, err := s.marshallSwap(ctx, &swp)
584-
if err != nil {
585-
return nil, err
603+
// Check if this swap is within our pagination window.
604+
if idx >= int(req.IndexOffset) {
605+
// If maxSwaps is 0, we return all swaps.
606+
// Otherwise, check if we've reached our limit.
607+
if maxSwaps == 0 || len(rpcSwaps) < maxSwaps {
608+
rpcSwap, err := s.marshallSwap(ctx, &swp)
609+
if err != nil {
610+
return nil, err
611+
}
612+
rpcSwaps = append(rpcSwaps, rpcSwap)
613+
lastIdx = idx
614+
}
615+
586616
}
587-
rpcSwaps = append(rpcSwaps, rpcSwap)
588617
idx++
589618
}
590-
return &looprpc.ListSwapsResponse{Swaps: rpcSwaps}, nil
619+
620+
response := looprpc.ListSwapsResponse{
621+
Swaps: rpcSwaps,
622+
FirstIndexOffset: req.IndexOffset,
623+
LastIndexOffset: uint64(lastIdx),
624+
TotalFilteredSwaps: uint64(idx),
625+
}
626+
return &response, nil
591627
}
592628

593629
// filterSwap filters the given swap based on the provided filter.

0 commit comments

Comments
 (0)