44 "context"
55 "fmt"
66 prand "math/rand"
7+ "math/rand/v2"
78 "testing"
89 "time"
910
@@ -29,30 +30,180 @@ func sendTest(t *testing.T, ctx context.Context, cfg *Config) {
2930 ctxt , cancel := context .WithTimeout (ctxb , cfg .TestTimeout )
3031 defer cancel ()
3132
33+ sendType := stringToAssetType (cfg .SendAssetType )
34+
3235 t .Logf ("Running send test, sending %d asset(s) of type %v %d times" ,
33- cfg .NumAssets , cfg . SendType , cfg .NumSends )
36+ cfg .NumAssets , sendType , cfg .NumSends )
3437 for i := 1 ; i <= cfg .NumSends ; i ++ {
3538 send , receive , ok := pickSendNode (
36- t , ctx , cfg .NumAssets , cfg . SendType , alice , bob ,
39+ t , ctx , cfg .NumAssets , sendType , alice , bob ,
3740 )
3841 if ! ok {
3942 t .Fatalf ("Aborting send test at attempt %d of %d as " +
4043 "no node has enough balance to send %d " +
4144 "assets of type %v" , i , cfg .NumSends ,
42- cfg .NumAssets , cfg . SendType )
45+ cfg .NumAssets , sendType )
4346 return
4447 }
4548
4649 sendAssets (
47- t , ctxt , cfg .NumAssets , cfg . SendType , send , receive ,
50+ t , ctxt , cfg .NumAssets , sendType , send , receive ,
4851 bitcoinClient , cfg .TestTimeout ,
4952 )
5053
5154 t .Logf ("Finished %d of %d send operations" , i , cfg .NumSends )
5255 }
5356}
5457
55- // sendAssets sends the given number of assets of the given type from the given
58+ // sendTestV2 checks that we are able to send assets between the two nodes. It
59+ // is a more performant and lightweight version of sendTest, as it uses less
60+ // assertions and RPC calls.
61+ func sendTestV2 (t * testing.T , ctx context.Context , cfg * Config ) {
62+ // Start by initializing all our client connections.
63+ alice , bob , bitcoinClient := initClients (t , ctx , cfg )
64+
65+ ctxb := context .Background ()
66+ ctxt , cancel := context .WithTimeout (ctxb , cfg .TestTimeout )
67+ defer cancel ()
68+
69+ sendType := stringToAssetType (cfg .SendAssetType )
70+
71+ // Alice is set to be the minter in mintV2, so we use Alice's universe.
72+ uniHost := fmt .Sprintf ("%s:%d" , alice .cfg .Host , alice .cfg .Port )
73+
74+ // Let's make sure Bob is aware of all the assets that Alice may have
75+ // minted.
76+ itest .SyncUniverses (
77+ ctx , t , bob , alice , uniHost , cfg .TestTimeout ,
78+ itest .WithSyncMode (itest .SyncModeFull ),
79+ )
80+
81+ // We now retrieve Alice and Bob's balances just once, and will re-use
82+ // them in future function calls. Any update to the balances will be
83+ // directly applied to these response objects, to skip future calls to
84+ // ListBalances.
85+ resAlice , err := alice .ListBalances (ctx , & taprpc.ListBalancesRequest {
86+ GroupBy : & taprpc.ListBalancesRequest_AssetId {
87+ AssetId : true ,
88+ },
89+ })
90+ require .NoError (t , err )
91+
92+ resBob , err := bob .ListBalances (ctx , & taprpc.ListBalancesRequest {
93+ GroupBy : & taprpc.ListBalancesRequest_AssetId {
94+ AssetId : true ,
95+ },
96+ })
97+ require .NoError (t , err )
98+
99+ for i := 1 ; i <= cfg .NumSends ; i ++ {
100+ var (
101+ sender , receiver * rpcClient
102+ senderAssets map [string ]* taprpc.AssetBalance
103+ )
104+
105+ // Assets may be sent in both directions, so we make a random
106+ // draw to conclude who the sender is.
107+ draw := rand .IntN (2 )
108+
109+ switch draw {
110+ case 0 :
111+ sender = alice
112+ senderAssets = resAlice .AssetBalances
113+ receiver = bob
114+
115+ case 1 :
116+ sender = bob
117+ senderAssets = resBob .AssetBalances
118+ receiver = alice
119+ }
120+
121+ sendAssetV2 (
122+ t , ctxt , cfg .NumAssets , sendType , senderAssets ,
123+ sender , receiver , bitcoinClient , cfg .TestTimeout ,
124+ )
125+ }
126+ }
127+
128+ // sendAssetV2 sends a certain amount of assets of a specific type from a sender
129+ // to a receiver. It will scan the balance of the sender and find a suitable
130+ // asset to carry out the send, then will dispatch the send and assert its
131+ // completion.
132+ func sendAssetV2 (t * testing.T , ctx context.Context , numAssets uint64 ,
133+ assetType taprpc.AssetType , assets map [string ]* taprpc.AssetBalance ,
134+ sender , receiver * rpcClient , bitcoinClient * rpcclient.Client ,
135+ timeout time.Duration ) {
136+
137+ // Look over the sender's balances to see if any asset balance qualifies
138+ // for this send.
139+ var (
140+ assetID []byte
141+ balance * taprpc.AssetBalance
142+ )
143+ for _ , v := range assets {
144+ if v .Balance >= numAssets &&
145+ v .AssetGenesis .AssetType == assetType {
146+
147+ assetID = v .AssetGenesis .AssetId
148+ balance = v
149+
150+ break
151+ }
152+ }
153+
154+ // No balance satisfies the amount of this send, we can skip this round.
155+ if assetID == nil {
156+ t .Logf ("%s could not send %v assets, no available balance" ,
157+ sender .cfg .Name , numAssets )
158+
159+ return
160+ }
161+
162+ t .Logf ("%s sending %v assets to %s" , sender .cfg .Name , numAssets ,
163+ receiver .cfg .Name )
164+
165+ // Receiver creates the address to receive the assets.
166+ addr , err := receiver .NewAddr (ctx , & taprpc.NewAddrRequest {
167+ AssetId : assetID ,
168+ Amt : numAssets ,
169+ ProofCourierAddr : fmt .Sprintf (
170+ "%s://%s:%d" , proof .UniverseRpcCourierType ,
171+ sender .cfg .Host , sender .cfg .Port ,
172+ ),
173+ })
174+ require .NoError (t , err )
175+
176+ t .Logf ("%s created address %v" , receiver .cfg .Name , addr .String ())
177+
178+ // Sender initiates the send.
179+ _ , err = sender .SendAsset (ctx , & taprpc.SendAssetRequest {
180+ TapAddrs : []string {addr .Encoded },
181+ })
182+ require .NoError (t , err )
183+ t .Logf ("%s sent assets to address %v" , sender .cfg .Name , addr .String ())
184+
185+ // We assert the receiver detects the spend.
186+ itest .AssertAddrEventCustomTimeout (
187+ t , receiver , addr , 1 , statusDetected , timeout ,
188+ )
189+ t .Logf ("%s detected send" , receiver .cfg .Name )
190+
191+ // Mine a block to confirm the transfer.
192+ itest .MineBlocks (t , bitcoinClient , 1 , 0 )
193+ t .Log ("Mined 1 block" )
194+
195+ // Assert that the transfer is now completed
196+ itest .AssertAddrEventCustomTimeout (
197+ t , receiver , addr , 1 , statusCompleted , timeout ,
198+ )
199+ t .Logf ("%s completed send of %v assets" , sender .cfg .Name , numAssets )
200+
201+ // If everything completed correctly, subtract the asset amount from the
202+ // sender's asset balance.
203+ balance .Balance -= numAssets
204+ }
205+
206+ // sendAsset sends the given number of assets of the given type from the given
56207// node to the other node.
57208func sendAssets (t * testing.T , ctx context.Context , numAssets uint64 ,
58209 assetType taprpc.AssetType , send , receive * rpcClient ,
0 commit comments