@@ -4,15 +4,19 @@ import (
44 "context"
55 "os"
66 "testing"
7+ "time"
78
89 "github.com/btcsuite/btcd/btcutil"
910 "github.com/btcsuite/btcd/chaincfg"
1011 "github.com/btcsuite/btclog/v2"
1112 "github.com/lightninglabs/lndclient"
1213 "github.com/lightninglabs/loop"
1314 "github.com/lightninglabs/loop/labels"
15+ "github.com/lightninglabs/loop/loopdb"
1416 "github.com/lightninglabs/loop/looprpc"
17+ "github.com/lightninglabs/loop/swap"
1518 mock_lnd "github.com/lightninglabs/loop/test"
19+ "github.com/lightningnetwork/lnd/lntypes"
1620 "github.com/lightningnetwork/lnd/lnwire"
1721 "github.com/lightningnetwork/lnd/routing/route"
1822 "github.com/stretchr/testify/require"
@@ -595,3 +599,273 @@ func TestHasBandwidth(t *testing.T) {
595599 })
596600 }
597601}
602+
603+ // TestListSwapsFilterAndPagination tests the filtering and
604+ // paging of the ListSwaps command.
605+ func TestListSwapsFilterAndPagination (t * testing.T ) {
606+ // Create a set of test swaps of various types which contain the minimal
607+ // viable amount of info to successfully be run through marshallSwap.
608+ swapInOrder0 := loop.SwapInfo {
609+ SwapStateData : loopdb.SwapStateData {
610+ State : loopdb .StateInitiated ,
611+ Cost : loopdb.SwapCost {},
612+ },
613+ SwapContract : loopdb.SwapContract {
614+ InitiationTime : time .Now ().Add (time .Duration (0 )),
615+ },
616+ LastUpdate : time .Now (),
617+ SwapHash : lntypes.Hash {1 },
618+ SwapType : swap .Type (swap .TypeIn ),
619+ HtlcAddressP2WSH : testnetAddr ,
620+ HtlcAddressP2TR : testnetAddr ,
621+ }
622+
623+ swapOutOrder1 := loop.SwapInfo {
624+ SwapStateData : loopdb.SwapStateData {
625+ State : loopdb .StateInitiated ,
626+ Cost : loopdb.SwapCost {},
627+ },
628+ SwapContract : loopdb.SwapContract {
629+ InitiationTime : time .Now ().Add (time .Duration (50 )),
630+ },
631+ LastUpdate : time .Now (),
632+ SwapHash : lntypes.Hash {2 },
633+ SwapType : swap .Type (swap .TypeOut ),
634+ HtlcAddressP2WSH : testnetAddr ,
635+ HtlcAddressP2TR : testnetAddr ,
636+ }
637+
638+ swapOutOrder2 := loop.SwapInfo {
639+ SwapStateData : loopdb.SwapStateData {
640+ State : loopdb .StateInitiated ,
641+ Cost : loopdb.SwapCost {},
642+ },
643+ SwapContract : loopdb.SwapContract {
644+ InitiationTime : time .Now ().Add (time .Duration (100 )),
645+ },
646+ LastUpdate : time .Now (),
647+ SwapHash : lntypes.Hash {3 },
648+ SwapType : swap .Type (swap .TypeOut ),
649+ HtlcAddressP2WSH : testnetAddr ,
650+ HtlcAddressP2TR : testnetAddr ,
651+ }
652+
653+ mockSwaps := []loop.SwapInfo {swapInOrder0 , swapOutOrder1 , swapOutOrder2 }
654+
655+ tests := []struct {
656+ name string
657+ // Define the mock swaps that will be stored in the mock client.
658+ mockSwaps []loop.SwapInfo
659+ req * looprpc.ListSwapsRequest
660+ expectedReturnedSwaps []lntypes.Hash
661+ expectedFirstIdx uint64
662+ expectedLastIdx uint64
663+ expectedFilteredTotalCount uint64
664+ }{
665+ {
666+ name : "fetch all swaps no pagination" ,
667+ mockSwaps : mockSwaps ,
668+ req : & looprpc.ListSwapsRequest {},
669+ expectedReturnedSwaps : []lntypes.Hash {
670+ swapOutOrder2 .SwapHash ,
671+ swapOutOrder1 .SwapHash ,
672+ swapInOrder0 .SwapHash ,
673+ },
674+ expectedFirstIdx : 0 ,
675+ expectedLastIdx : 2 ,
676+ expectedFilteredTotalCount : 3 ,
677+ },
678+ {
679+ name : "fetch all swaps no pagination alt-order1" ,
680+ mockSwaps : []loop.SwapInfo {swapOutOrder1 , swapInOrder0 , swapOutOrder2 },
681+ req : & looprpc.ListSwapsRequest {},
682+ expectedReturnedSwaps : []lntypes.Hash {
683+ swapOutOrder2 .SwapHash ,
684+ swapOutOrder1 .SwapHash ,
685+ swapInOrder0 .SwapHash ,
686+ },
687+ expectedFirstIdx : 0 ,
688+ expectedLastIdx : 2 ,
689+ expectedFilteredTotalCount : 3 ,
690+ },
691+ {
692+ name : "fetch all swaps no pagination alt-order2" ,
693+ mockSwaps : []loop.SwapInfo {swapOutOrder2 , swapOutOrder1 , swapInOrder0 },
694+ req : & looprpc.ListSwapsRequest {},
695+ expectedReturnedSwaps : []lntypes.Hash {
696+ swapOutOrder2 .SwapHash ,
697+ swapOutOrder1 .SwapHash ,
698+ swapInOrder0 .SwapHash ,
699+ },
700+ expectedFirstIdx : 0 ,
701+ expectedLastIdx : 2 ,
702+ expectedFilteredTotalCount : 3 ,
703+ },
704+ {
705+ name : "fetch swaps-ins no pagination" ,
706+ mockSwaps : mockSwaps ,
707+ req : & looprpc.ListSwapsRequest {
708+ ListSwapFilter : & looprpc.ListSwapsFilter {
709+ SwapType : looprpc .ListSwapsFilter_LOOP_IN },
710+ },
711+ expectedReturnedSwaps : []lntypes.Hash {
712+ swapInOrder0 .SwapHash ,
713+ },
714+ expectedFirstIdx : 0 ,
715+ expectedLastIdx : 0 ,
716+ expectedFilteredTotalCount : 1 ,
717+ },
718+ {
719+ name : "fetch swaps-outs no pagination" ,
720+ mockSwaps : mockSwaps ,
721+ req : & looprpc.ListSwapsRequest {
722+ ListSwapFilter : & looprpc.ListSwapsFilter {
723+ SwapType : looprpc .ListSwapsFilter_LOOP_OUT ,
724+ },
725+ },
726+ expectedReturnedSwaps : []lntypes.Hash {
727+ swapOutOrder2 .SwapHash ,
728+ swapOutOrder1 .SwapHash ,
729+ },
730+ expectedFirstIdx : 0 ,
731+ expectedLastIdx : 1 ,
732+ expectedFilteredTotalCount : 2 ,
733+ },
734+ {
735+ name : "fetch swaps-outs increment start_index" ,
736+ mockSwaps : mockSwaps ,
737+ req : & looprpc.ListSwapsRequest {
738+ ListSwapFilter : & looprpc.ListSwapsFilter {
739+ SwapType : looprpc .ListSwapsFilter_LOOP_OUT ,
740+ },
741+ IndexOffset : 1 ,
742+ },
743+ expectedReturnedSwaps : []lntypes.Hash {
744+ swapOutOrder1 .SwapHash ,
745+ },
746+ expectedFirstIdx : 1 ,
747+ expectedLastIdx : 1 ,
748+ expectedFilteredTotalCount : 2 ,
749+ },
750+ {
751+ name : "fetch all swaps set swap limit" ,
752+ mockSwaps : mockSwaps ,
753+ req : & looprpc.ListSwapsRequest {
754+ MaxSwaps : 2 ,
755+ },
756+ expectedReturnedSwaps : []lntypes.Hash {
757+ swapOutOrder2 .SwapHash ,
758+ swapOutOrder1 .SwapHash ,
759+ },
760+ expectedFirstIdx : 0 ,
761+ expectedLastIdx : 1 ,
762+ expectedFilteredTotalCount : 3 ,
763+ },
764+ {
765+ name : "fetch all swaps set swap limit set start index" ,
766+ mockSwaps : mockSwaps ,
767+ req : & looprpc.ListSwapsRequest {
768+ IndexOffset : 1 ,
769+ MaxSwaps : 1 ,
770+ },
771+ expectedReturnedSwaps : []lntypes.Hash {
772+ swapOutOrder1 .SwapHash ,
773+ },
774+ expectedFirstIdx : 1 ,
775+ expectedLastIdx : 1 ,
776+ expectedFilteredTotalCount : 3 ,
777+ },
778+ {
779+ name : "fetch all swaps set start index out of bounds" ,
780+ mockSwaps : mockSwaps ,
781+ req : & looprpc.ListSwapsRequest {
782+ IndexOffset : 5 ,
783+ },
784+ expectedReturnedSwaps : []lntypes.Hash {},
785+ expectedFirstIdx : 5 ,
786+ expectedLastIdx : 0 ,
787+ expectedFilteredTotalCount : 3 ,
788+ },
789+ {
790+ name : "fetch all swaps set limit to 0" ,
791+ mockSwaps : mockSwaps ,
792+ req : & looprpc.ListSwapsRequest {
793+ MaxSwaps : 0 ,
794+ },
795+ expectedReturnedSwaps : []lntypes.Hash {
796+ swapOutOrder2 .SwapHash ,
797+ swapOutOrder1 .SwapHash ,
798+ swapInOrder0 .SwapHash ,
799+ },
800+ expectedLastIdx : 2 ,
801+ expectedFilteredTotalCount : 3 ,
802+ },
803+ }
804+
805+ for _ , test := range tests {
806+ t .Run (test .name , func (t * testing.T ) {
807+ t .Parallel ()
808+
809+ // Create the swap client server with our mock client.
810+ server := & swapClientServer {
811+ swaps : make (map [lntypes.Hash ]loop.SwapInfo ),
812+ }
813+
814+ // Populate the server's swap cache with our mock swaps.
815+ for _ , swap := range test .mockSwaps {
816+ server .swaps [swap .SwapHash ] = swap
817+ }
818+
819+ // Call the ListSwaps method.
820+ resp , err := server .ListSwaps (context .Background (), test .req )
821+ require .NoError (t , err )
822+
823+ require .Len (
824+ t ,
825+ resp .Swaps ,
826+ len (test .expectedReturnedSwaps ),
827+ "incorrect returned count" ,
828+ )
829+
830+ require .Equal (
831+ t ,
832+ test .expectedFirstIdx ,
833+ resp .FirstIndexOffset ,
834+ "incorrect first index" ,
835+ )
836+
837+ require .Equal (
838+ t ,
839+ test .expectedLastIdx ,
840+ resp .LastIndexOffset ,
841+ "incorrect last index" ,
842+ )
843+
844+ require .Equal (
845+ t ,
846+ test .expectedFilteredTotalCount ,
847+ resp .TotalFilteredSwaps ,
848+ "incorrect total" ,
849+ )
850+
851+ // Subtest function to check consistent iteration order.
852+ swapOrderCheck := func (
853+ hashes []lntypes.Hash ,
854+ swaps * looprpc.ListSwapsResponse ) {
855+ for idx , aswap := range swaps .Swaps {
856+ newhash , err := lntypes .MakeHash (aswap .GetIdBytes ())
857+ require .NoError (t , err )
858+ require .Equal (
859+ t ,
860+ hashes [idx ],
861+ newhash ,
862+ "iteration order mismatch" ,
863+ )
864+
865+ }
866+
867+ }
868+ swapOrderCheck (test .expectedReturnedSwaps , resp )
869+ })
870+ }
871+ }
0 commit comments