@@ -290,6 +290,142 @@ func createTestAssetNetwork(t *harnessTest, net *NetworkHarness, charlieTap,
290290 return chanPointCD , chanPointDY , chanPointEF
291291}
292292
293+ func createTestAssetNetworkGroupKey (ctx context.Context , t * harnessTest ,
294+ net * NetworkHarness , charlieTap , daveTap , erinTap , fabiaTap ,
295+ universeTap * tapClient , mintedAssets []* taprpc.Asset , assetSendAmount ,
296+ charlieFundingAmount , erinFundingAmount uint64 ,
297+ pushSat int64 ) (* lnrpc.ChannelPoint , * lnrpc.ChannelPoint ) {
298+
299+ var groupKey []byte
300+ for _ , mintedAsset := range mintedAssets {
301+ require .NotNil (t .t , mintedAsset .AssetGroup )
302+
303+ if groupKey == nil {
304+ groupKey = mintedAsset .AssetGroup .TweakedGroupKey
305+
306+ continue
307+ }
308+
309+ require .Equal (
310+ t .t , groupKey , mintedAsset .AssetGroup .TweakedGroupKey ,
311+ )
312+ }
313+
314+ // We need to send some assets to Erin, so he can fund an asset channel
315+ // with Fabia.
316+ sendAssetsEqualAmounts (
317+ ctx , t , erinTap , charlieTap , universeTap , mintedAssets ,
318+ assetSendAmount / 2 , 0 ,
319+ )
320+
321+ t .Logf ("Opening asset channels..." )
322+
323+ // The first channel we create has a push amount, so Charlie can receive
324+ // payments immediately and not run into the channel reserve issue.
325+ fundRespCD , err := charlieTap .FundChannel (
326+ ctx , & tchrpc.FundChannelRequest {
327+ AssetAmount : charlieFundingAmount ,
328+ GroupKey : groupKey ,
329+ PeerPubkey : daveTap .node .PubKey [:],
330+ FeeRateSatPerVbyte : 5 ,
331+ PushSat : pushSat ,
332+ },
333+ )
334+ require .NoError (t .t , err )
335+ t .Logf ("Funded channel between Charlie and Dave: %v" , fundRespCD )
336+
337+ fundRespEF , err := erinTap .FundChannel (
338+ ctx , & tchrpc.FundChannelRequest {
339+ AssetAmount : erinFundingAmount ,
340+ GroupKey : groupKey ,
341+ PeerPubkey : fabiaTap .node .PubKey [:],
342+ FeeRateSatPerVbyte : 5 ,
343+ PushSat : pushSat ,
344+ },
345+ )
346+ require .NoError (t .t , err )
347+ t .Logf ("Funded channel between Erin and Fabia: %v" , fundRespEF )
348+
349+ // Make sure the pending channel shows up in the list and has the
350+ // custom records set as JSON.
351+ assertPendingChannels (
352+ t .t , charlieTap .node , mintedAssets [1 ], 1 , charlieFundingAmount ,
353+ 0 ,
354+ )
355+ assertPendingChannels (
356+ t .t , erinTap .node , mintedAssets [0 ], 1 , erinFundingAmount / 2 , 0 ,
357+ )
358+ assertPendingChannels (
359+ t .t , erinTap .node , mintedAssets [1 ], 1 , erinFundingAmount / 2 , 0 ,
360+ )
361+
362+ // Now that we've looked at the pending channels, let's actually confirm
363+ // all three of them.
364+ mineBlocks (t , net , 6 , 2 )
365+
366+ chanPointCD := & lnrpc.ChannelPoint {
367+ OutputIndex : uint32 (fundRespCD .OutputIndex ),
368+ FundingTxid : & lnrpc.ChannelPoint_FundingTxidStr {
369+ FundingTxidStr : fundRespCD .Txid ,
370+ },
371+ }
372+ chanPointEF := & lnrpc.ChannelPoint {
373+ OutputIndex : uint32 (fundRespEF .OutputIndex ),
374+ FundingTxid : & lnrpc.ChannelPoint_FundingTxidStr {
375+ FundingTxidStr : fundRespEF .Txid ,
376+ },
377+ }
378+
379+ return chanPointCD , chanPointEF
380+ }
381+
382+ func sendAssetsEqualAmounts (ctx context.Context , t * harnessTest ,
383+ recipient , sender , universe * tapClient , mintedAssets []* taprpc.Asset ,
384+ assetSendAmount uint64 , previousSends uint64 ) {
385+
386+ numTranches := uint64 (len (mintedAssets ))
387+ for idx , mintedAsset := range mintedAssets {
388+ assetID := mintedAsset .AssetGenesis .AssetId
389+ trancheAmount := assetSendAmount / numTranches
390+ recipientAddr , err := recipient .NewAddr (
391+ ctx , & taprpc.NewAddrRequest {
392+ Amt : trancheAmount ,
393+ AssetId : assetID ,
394+ ProofCourierAddr : fmt .Sprintf (
395+ "%s://%s" , proof .UniverseRpcCourierType ,
396+ universe .node .Cfg .LitAddr (),
397+ ),
398+ },
399+ )
400+ require .NoError (t .t , err )
401+
402+ t .Logf ("Sending %v asset units to %s..." , trancheAmount ,
403+ recipient .node .Cfg .Name )
404+
405+ // We assume that we sent the same size in a previous send.
406+ totalSent := trancheAmount + (previousSends * trancheAmount )
407+
408+ // Send the assets to recipient.
409+ itest .AssertAddrCreated (
410+ t .t , recipient , mintedAsset , recipientAddr ,
411+ )
412+ sendResp , err := sender .SendAsset (ctx , & taprpc.SendAssetRequest {
413+ TapAddrs : []string {recipientAddr .Encoded },
414+ })
415+ require .NoError (t .t , err )
416+ itest .ConfirmAndAssertOutboundTransfer (
417+ t .t , t .lndHarness .Miner .Client , sender , sendResp ,
418+ assetID ,
419+ []uint64 {mintedAsset .Amount - totalSent , trancheAmount },
420+ int (previousSends * numTranches )+ idx ,
421+ int (previousSends * numTranches )+ idx + 1 ,
422+ )
423+ itest .AssertNonInteractiveRecvComplete (
424+ t .t , recipient , int (previousSends * numTranches )+ idx + 1 ,
425+ )
426+ }
427+ }
428+
293429func assertNumAssetUTXOs (t * testing.T , tapdClient * tapClient ,
294430 numUTXOs int ) * taprpc.ListUtxosResponse {
295431
@@ -472,10 +608,13 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
472608 pendingChan .Channel .CustomChannelData , & pendingJSON ,
473609 )
474610 require .NoError (t , err )
475- require .Len (t , pendingJSON .Assets , 1 )
611+ require .GreaterOrEqual (t , len ( pendingJSON .Assets ) , 1 )
476612
477613 require .NotZero (t , pendingJSON .Assets [0 ].Capacity )
478614
615+ pendingFormatted , _ := json .MarshalIndent (pendingJSON , "" , " " )
616+ t .Logf ("Pending channel: %v" , string (pendingFormatted ))
617+
479618 // Check the decimal display of the channel funding blob. If no explicit
480619 // value was set, we assume and expect the value of 0.
481620 var expectedDecimalDisplay uint8
@@ -493,9 +632,7 @@ func assertPendingChannels(t *testing.T, node *HarnessNode,
493632 // Check the balance of the pending channel.
494633 assetID := mintedAsset .AssetGenesis .AssetId
495634 pendingLocalBalance , pendingRemoteBalance , _ , _ :=
496- getAssetChannelBalance (
497- t , node , assetID , true ,
498- )
635+ getAssetChannelBalance (t , node , [][]byte {assetID }, true )
499636 require .EqualValues (t , localSum , pendingLocalBalance )
500637 require .EqualValues (t , remoteSum , pendingRemoteBalance )
501638}
@@ -621,7 +758,7 @@ func getChannelCustomData(src, dst *HarnessNode) (*rfqmsg.JsonAssetChanInfo,
621758 return & assetData .Assets [0 ], nil
622759}
623760
624- func getAssetChannelBalance (t * testing.T , node * HarnessNode , assetID []byte ,
761+ func getAssetChannelBalance (t * testing.T , node * HarnessNode , assetIDs [] []byte ,
625762 pending bool ) (uint64 , uint64 , uint64 , uint64 ) {
626763
627764 ctxb := context .Background ()
@@ -642,9 +779,19 @@ func getAssetChannelBalance(t *testing.T, node *HarnessNode, assetID []byte,
642779 balances = assetBalance .PendingChannels
643780 }
644781
782+ idMatch := func (assetIDString string ) bool {
783+ for _ , groupedID := range assetIDs {
784+ if assetIDString == hex .EncodeToString (groupedID ) {
785+ return true
786+ }
787+ }
788+
789+ return false
790+ }
791+
645792 var localSum , remoteSum uint64
646793 for assetIDString := range balances {
647- if assetIDString != hex . EncodeToString ( assetID ) {
794+ if ! idMatch ( assetIDString ) {
648795 continue
649796 }
650797
@@ -2017,8 +2164,27 @@ func logBalance(t *testing.T, nodes []*HarnessNode, assetID []byte,
20172164 time .Sleep (time .Millisecond * 250 )
20182165
20192166 for _ , node := range nodes {
2020- local , remote , localSat , remoteSat :=
2021- getAssetChannelBalance (t , node , assetID , false )
2167+ local , remote , localSat , remoteSat := getAssetChannelBalance (
2168+ t , node , [][]byte {assetID }, false ,
2169+ )
2170+
2171+ t .Logf ("%-7s balance: local=%-9d remote=%-9d, localSat=%-9d, " +
2172+ "remoteSat=%-9d (%v)" , node .Cfg .Name , local , remote ,
2173+ localSat , remoteSat , occasion )
2174+ }
2175+ }
2176+
2177+ func logBalanceGroup (t * testing.T , nodes []* HarnessNode , assetIDs [][]byte ,
2178+ occasion string ) {
2179+
2180+ t .Helper ()
2181+
2182+ time .Sleep (time .Millisecond * 250 )
2183+
2184+ for _ , node := range nodes {
2185+ local , remote , localSat , remoteSat := getAssetChannelBalance (
2186+ t , node , assetIDs , false ,
2187+ )
20222188
20232189 t .Logf ("%-7s balance: local=%-9d remote=%-9d, localSat=%-9d, " +
20242190 "remoteSat=%-9d (%v)" , node .Cfg .Name , local , remote ,
0 commit comments