@@ -701,6 +701,165 @@ func runMultiSendTest(ctxt context.Context, t *harnessTest, alice,
701701 }
702702}
703703
704+ // testAddrReceivesPagination tests the pagination of
705+ // AddrReceives
706+ func testAddrReceivesPagination (t * harnessTest ) {
707+ // First, mint a few assets, so we have some to create addresses for.
708+ rpcAssets := MintAssetsConfirmBatch (
709+ t .t , t .lndHarness .Miner ().Client , t .tapd ,
710+ []* mintrpc.MintAssetRequest {
711+ simpleAssets [0 ], issuableAssets [0 ],
712+ },
713+ )
714+
715+ ctxb := context .Background ()
716+ ctxt , cancel := context .WithTimeout (ctxb , defaultWaitTimeout )
717+ defer cancel ()
718+
719+ // We'll make a second node now that'll be the receiver of all the
720+ // assets made above.
721+ bobLnd := t .lndHarness .NewNodeWithCoins ("Bob" , nil )
722+ secondTapd := setupTapdHarness (t .t , t , bobLnd , t .universeServer )
723+ defer func () {
724+ require .NoError (t .t , secondTapd .stop (! * noDelete ))
725+ }()
726+
727+ const numAddresses = 6
728+ for i := range numAddresses {
729+ // Use different assets for variety
730+ assetIdx := i % len (rpcAssets )
731+ asset := rpcAssets [assetIdx ]
732+
733+ addr , events := NewAddrWithEventStream (
734+ t .t , secondTapd , & taprpc.NewAddrRequest {
735+ AssetId : asset .AssetGenesis .AssetId ,
736+ Amt : uint64 (10 ),
737+ AssetVersion : asset .Version ,
738+ },
739+ )
740+
741+ AssertAddrCreated (t .t , secondTapd , asset , addr )
742+
743+ // Send assets to the address
744+ _ , sendEvents := sendAssetsToAddr (t , t .tapd , addr )
745+
746+ AssertAddrEvent (t .t , secondTapd , addr , 1 , statusDetected )
747+
748+ // Mine a block to make sure the events are marked as confirmed.
749+ MineBlocks (t .t , t .lndHarness .Miner ().Client , 1 , 1 )
750+
751+ // Eventually the event should be marked as confirmed.
752+ AssertAddrEvent (t .t , secondTapd , addr , 1 , statusConfirmed )
753+
754+ // Make sure we have imported and finalized all proofs.
755+ AssertNonInteractiveRecvComplete (t .t , secondTapd , i + 1 )
756+ AssertSendEventsComplete (t .t , addr .ScriptKey , sendEvents )
757+
758+ // Make sure the receiver has received all events in order for
759+ // the address.
760+ AssertReceiveEvents (t .t , addr , events )
761+ }
762+
763+ // Test 1: limit
764+ resp , err := secondTapd .AddrReceives (ctxt , & taprpc.AddrReceivesRequest {
765+ Limit : 3 ,
766+ })
767+ require .NoError (t .t , err )
768+ require .Len (t .t , resp .Events , 3 )
769+
770+ // Test 2: offset
771+ resp , err = secondTapd .AddrReceives (ctxt , & taprpc.AddrReceivesRequest {
772+ Offset : 2 ,
773+ Limit : 3 ,
774+ })
775+ require .NoError (t .t , err )
776+ require .Len (t .t , resp .Events , 3 )
777+
778+ // Test 3: Ascending direction (default)
779+ resp , err = secondTapd .AddrReceives (ctxt , & taprpc.AddrReceivesRequest {
780+ Limit : 5 ,
781+ Direction : 0 , // ascending
782+ })
783+ require .NoError (t .t , err )
784+ require .Len (t .t , resp .Events , 5 )
785+
786+ // Verify ascending order by checking creation times
787+ for i := 1 ; i < len (resp .Events ); i ++ {
788+ require .LessOrEqual (t .t ,
789+ resp .Events [i - 1 ].CreationTimeUnixSeconds ,
790+ resp .Events [i ].CreationTimeUnixSeconds ,
791+ )
792+ }
793+
794+ // Test 4: Descending direction
795+ resp , err = secondTapd .AddrReceives (ctxt , & taprpc.AddrReceivesRequest {
796+ Limit : 5 ,
797+ Direction : 1 , // descending
798+ })
799+ require .NoError (t .t , err )
800+ require .Len (t .t , resp .Events , 5 )
801+
802+ // Verify descending order by checking creation times
803+ for i := 1 ; i < len (resp .Events ); i ++ {
804+ require .GreaterOrEqual (t .t ,
805+ resp .Events [i - 1 ].CreationTimeUnixSeconds ,
806+ resp .Events [i ].CreationTimeUnixSeconds ,
807+ )
808+ }
809+
810+ // Test 5: Offset out of bounds
811+ resp , err = secondTapd .AddrReceives (ctxt ,
812+ & taprpc.AddrReceivesRequest {
813+ Offset : 100 ,
814+ Limit : 10 ,
815+ },
816+ )
817+ require .NoError (t .t , err )
818+ require .Len (t .t , resp .Events , 0 )
819+
820+ // Test 6: Test pagination through all results
821+ var allPaginatedEvents []* taprpc.AddrEvent
822+ offset := int32 (0 )
823+ limit := int32 (3 )
824+
825+ for {
826+ resp , err := secondTapd .AddrReceives (ctxt ,
827+ & taprpc.AddrReceivesRequest {
828+ Offset : offset ,
829+ Limit : limit ,
830+ },
831+ )
832+ require .NoError (t .t , err )
833+
834+ if len (resp .Events ) == 0 {
835+ break
836+ }
837+
838+ allPaginatedEvents = append (allPaginatedEvents , resp .Events ... )
839+ offset += limit
840+ }
841+
842+ // Should have collected all events
843+ require .Len (t .t , allPaginatedEvents , numAddresses )
844+
845+ // Test 7: Test negative offset and limit error
846+ _ , err = secondTapd .AddrReceives (ctxt ,
847+ & taprpc.AddrReceivesRequest {
848+ Offset : - 5 ,
849+ },
850+ )
851+ require .Error (t .t , err )
852+ require .Contains (t .t , err .Error (), "offset must be non-negative" )
853+
854+ _ , err = secondTapd .AddrReceives (ctxt ,
855+ & taprpc.AddrReceivesRequest {
856+ Limit : - 5 ,
857+ },
858+ )
859+ require .Error (t .t , err )
860+ require .Contains (t .t , err .Error (), "limit must be non-negative" )
861+ }
862+
704863// testUnknownTlvType tests that we can create an address with an unknown TLV
705864// type and that assets can be sent to it. We then modify a proof similarly and
706865// make sure it can be imported by a node correctly.
0 commit comments