@@ -4770,3 +4770,146 @@ func testCustomChannelsSelfPayment(ctx context.Context, net *NetworkHarness,
4770
4770
)
4771
4771
}
4772
4772
}
4773
+
4774
+ // testCustomChannelsMultiChannelPathfinding tests that multiple channels with
4775
+ // different assets are properly considered when pathfinding for payments.
4776
+ func testCustomChannelsMultiChannelPathfinding (ctx context.Context ,
4777
+ net * NetworkHarness , t * harnessTest ) {
4778
+
4779
+ lndArgs := slices .Clone (lndArgsTemplate )
4780
+ litdArgs := slices .Clone (litdArgsTemplate )
4781
+
4782
+ // We use Alice as the proof courier. But in order for Alice to also
4783
+ // use itself, we need to define its port upfront.
4784
+ alicePort := port .NextAvailablePort ()
4785
+ litdArgs = append (litdArgs , fmt .Sprintf (
4786
+ "--taproot-assets.proofcourieraddr=%s://%s" ,
4787
+ proof .UniverseRpcCourierType ,
4788
+ fmt .Sprintf (node .ListenerFormat , alicePort ),
4789
+ ))
4790
+
4791
+ // Next, we'll make Alice and Bob, who will be the main nodes under
4792
+ // test.
4793
+ alice , err := net .NewNodeWithPort (
4794
+ t .t , "Alice" , lndArgs , false , true , alicePort , litdArgs ... ,
4795
+ )
4796
+ require .NoError (t .t , err )
4797
+ bob , err := net .NewNode (
4798
+ t .t , "Bob" , lndArgs , false , true , litdArgs ... ,
4799
+ )
4800
+ require .NoError (t .t , err )
4801
+
4802
+ charlie , err := net .NewNode (
4803
+ t .t , "Charlie" , lndArgs , false , true , litdArgs ... ,
4804
+ )
4805
+ require .NoError (t .t , err )
4806
+
4807
+ // Now we'll connect all nodes, and also fund them with some coins.
4808
+ nodes := []* HarnessNode {alice , bob , charlie }
4809
+ connectAllNodes (t .t , net , nodes )
4810
+ fundAllNodes (t .t , net , nodes )
4811
+
4812
+ aliceTap := newTapClient (t .t , alice )
4813
+
4814
+ // Next, we'll mint an asset for Alice, who will be the node that opens
4815
+ // the channel outbound.
4816
+ mintedAssets1 := itest .MintAssetsConfirmBatch (
4817
+ t .t , t .lndHarness .Miner .Client , aliceTap ,
4818
+ []* mintrpc.MintAssetRequest {
4819
+ {
4820
+ Asset : itestAsset ,
4821
+ },
4822
+ },
4823
+ )
4824
+ cents := mintedAssets1 [0 ]
4825
+ assetIDCents := cents .AssetGenesis .AssetId
4826
+
4827
+ // We'll mint a second asset, representing british pences.
4828
+ mintedAssets2 := itest .MintAssetsConfirmBatch (
4829
+ t .t , t .lndHarness .Miner .Client , aliceTap ,
4830
+ []* mintrpc.MintAssetRequest {
4831
+ {
4832
+ Asset : & mintrpc.MintAsset {
4833
+ AssetType : taprpc .AssetType_NORMAL ,
4834
+ Name : "itest-asset-pences" ,
4835
+ AssetMeta : dummyMetaData ,
4836
+ Amount : 1_000_000 ,
4837
+ },
4838
+ },
4839
+ },
4840
+ )
4841
+ pences := mintedAssets2 [0 ]
4842
+ assetIDPences := pences .AssetGenesis .AssetId
4843
+
4844
+ t .Logf ("Minted %d lightning cents and %d lightning pences, syncing " +
4845
+ "universes..." , cents .Amount , pences .Amount )
4846
+ syncUniverses (t .t , aliceTap , bob )
4847
+ t .Logf ("Universes synced between all nodes, distributing assets..." )
4848
+
4849
+ // With the assets created, and synced -- we'll now open the channel
4850
+ // between Alice and Bob.
4851
+ t .Logf ("Opening asset channel with cents..." )
4852
+ assetFundResp1 , err := aliceTap .FundChannel (
4853
+ ctx , & tchrpc.FundChannelRequest {
4854
+ AssetAmount : fundingAmount ,
4855
+ AssetId : assetIDCents ,
4856
+ PeerPubkey : bob .PubKey [:],
4857
+ FeeRateSatPerVbyte : 5 ,
4858
+ },
4859
+ )
4860
+ require .NoError (t .t , err )
4861
+ t .Logf ("Funded cents channel between Alice and Bob: %v" , assetFundResp1 )
4862
+
4863
+ // With the channel open, mine a block to confirm it.
4864
+ mineBlocks (t , net , 6 , 1 )
4865
+
4866
+ t .Logf ("Opening asset channel with pences..." )
4867
+ assetFundResp2 , err := aliceTap .FundChannel (
4868
+ ctx , & tchrpc.FundChannelRequest {
4869
+ AssetAmount : fundingAmount ,
4870
+ AssetId : assetIDPences ,
4871
+ PeerPubkey : bob .PubKey [:],
4872
+ FeeRateSatPerVbyte : 5 ,
4873
+ },
4874
+ )
4875
+ require .NoError (t .t , err )
4876
+ t .Logf ("Funded pences channel between Alice and Bob: %v" ,
4877
+ assetFundResp2 )
4878
+
4879
+ // With the channel open, mine a block to confirm it.
4880
+ mineBlocks (t , net , 6 , 1 )
4881
+
4882
+ t .Logf ("Opening normal channel between Bob and Charlie..." )
4883
+ satChanPoint := openChannelAndAssert (
4884
+ t , net , bob , charlie , lntest.OpenChannelParams {
4885
+ Amt : 10_000_000 ,
4886
+ SatPerVByte : 5 ,
4887
+ },
4888
+ )
4889
+ defer closeChannelAndAssert (t , net , charlie , satChanPoint , false )
4890
+
4891
+ // Before we start sending out payments, let's make sure each node can
4892
+ // see the other one in the graph and has all required features.
4893
+ require .NoError (t .t , t .lndHarness .AssertNodeKnown (alice , bob ))
4894
+ require .NoError (t .t , t .lndHarness .AssertNodeKnown (bob , alice ))
4895
+ require .NoError (t .t , t .lndHarness .AssertNodeKnown (alice , charlie ))
4896
+
4897
+ // We now make sure that the balance of the cents channel is higher on
4898
+ // Alice, by sending some of the pences to Bob in a keysend payment.
4899
+ const pencesKeySendAmount = 5_000
4900
+ sendAssetKeySendPayment (
4901
+ t .t , alice , bob , pencesKeySendAmount , assetIDPences ,
4902
+ fn .None [int64 ](),
4903
+ )
4904
+
4905
+ logBalance (t .t , nodes , assetIDCents , "cents, after keysend pences" )
4906
+ logBalance (t .t , nodes , assetIDPences , "pences, after keysend pences" )
4907
+
4908
+ // We now create a normal invoice on Charlie for some amount, then try
4909
+ // to pay it with pences.
4910
+ const btcInvoiceAmount = 500_00
4911
+ invoiceResp := createNormalInvoice (t .t , charlie , btcInvoiceAmount )
4912
+ payInvoiceWithAssets (
4913
+ t .t , alice , bob , invoiceResp .PaymentRequest , assetIDPences ,
4914
+ )
4915
+ }
0 commit comments