@@ -2892,6 +2892,144 @@ func testCustomChannelsLiquidityEdgeCasesGroup(ctx context.Context,
28922892	testCustomChannelsLiquidityEdgeCasesCore (ctx , net , t , true )
28932893}
28942894
2895+ // testCustomChannelsMultiRFQReceive tests that a node creating an invoice with 
2896+ // multiple RFQ quotes can actually guide the payer into using multiple private 
2897+ // taproot asset channels to pay the invoice. 
2898+ func  testCustomChannelsMultiRFQReceive (ctx  context.Context , net  * NetworkHarness ,
2899+ 	t  * harnessTest ) {
2900+ 
2901+ 	lndArgs  :=  slices .Clone (lndArgsTemplate )
2902+ 	litdArgs  :=  slices .Clone (litdArgsTemplate )
2903+ 
2904+ 	charlie , err  :=  net .NewNode (
2905+ 		t .t , "Charlie" , lndArgs , false , true , litdArgs ... ,
2906+ 	)
2907+ 	require .NoError (t .t , err )
2908+ 
2909+ 	litdArgs  =  append (litdArgs , fmt .Sprintf (
2910+ 		"--taproot-assets.proofcourieraddr=%s://%s" ,
2911+ 		proof .UniverseRpcCourierType , charlie .Cfg .LitAddr (),
2912+ 	))
2913+ 
2914+ 	dave , err  :=  net .NewNode (t .t , "Dave" , lndArgs , false , true , litdArgs ... )
2915+ 	require .NoError (t .t , err )
2916+ 	erin , err  :=  net .NewNode (t .t , "Erin" , lndArgs , false , true , litdArgs ... )
2917+ 	require .NoError (t .t , err )
2918+ 	fabia , err  :=  net .NewNode (
2919+ 		t .t , "Fabia" , lndArgs , false , true , litdArgs ... ,
2920+ 	)
2921+ 	require .NoError (t .t , err )
2922+ 	yara , err  :=  net .NewNode (
2923+ 		t .t , "Yara" , lndArgs , false , true , litdArgs ... ,
2924+ 	)
2925+ 	require .NoError (t .t , err )
2926+ 
2927+ 	nodes  :=  []* HarnessNode {charlie , dave , erin , fabia , yara }
2928+ 	connectAllNodes (t .t , net , nodes )
2929+ 	fundAllNodes (t .t , net , nodes )
2930+ 
2931+ 	// Let's create the tap clients. 
2932+ 	charlieTap  :=  newTapClient (t .t , charlie )
2933+ 	daveTap  :=  newTapClient (t .t , dave )
2934+ 	erinTap  :=  newTapClient (t .t , erin )
2935+ 	fabiaTap  :=  newTapClient (t .t , fabia )
2936+ 	yaraTap  :=  newTapClient (t .t , yara )
2937+ 
2938+ 	assetReq  :=  itest .CopyRequest (& mintrpc.MintAssetRequest {
2939+ 		Asset : itestAsset ,
2940+ 	})
2941+ 
2942+ 	assetReq .Asset .NewGroupedAsset  =  true 
2943+ 
2944+ 	// Mint an asset on Charlie and sync all nodes to Charlie as the 
2945+ 	// universe. 
2946+ 	mintedAssets  :=  itest .MintAssetsConfirmBatch (
2947+ 		t .t , t .lndHarness .Miner .Client , charlieTap ,
2948+ 		[]* mintrpc.MintAssetRequest {assetReq },
2949+ 	)
2950+ 	cents  :=  mintedAssets [0 ]
2951+ 	assetID  :=  cents .AssetGenesis .AssetId 
2952+ 	groupID  :=  cents .GetAssetGroup ().GetTweakedGroupKey ()
2953+ 
2954+ 	syncUniverses (t .t , charlieTap , dave , erin , fabia , yara )
2955+ 
2956+ 	multiRfqNodes  :=  multiRfqNodes {
2957+ 		charlie : itestNode {
2958+ 			Lnd :  charlie ,
2959+ 			Tapd : charlieTap ,
2960+ 		},
2961+ 		dave : itestNode {
2962+ 			Lnd :  dave ,
2963+ 			Tapd : daveTap ,
2964+ 		},
2965+ 		erin : itestNode {
2966+ 			Lnd :  erin ,
2967+ 			Tapd : erinTap ,
2968+ 		},
2969+ 		fabia : itestNode {
2970+ 			Lnd :  fabia ,
2971+ 			Tapd : fabiaTap ,
2972+ 		},
2973+ 		yara : itestNode {
2974+ 			Lnd :  yara ,
2975+ 			Tapd : yaraTap ,
2976+ 		},
2977+ 		universeTap : charlieTap ,
2978+ 	}
2979+ 
2980+ 	createTestMultiRFQAssetNetwork (
2981+ 		t , net , multiRfqNodes , cents , 10_000 , 10_000 , 10_000 ,
2982+ 	)
2983+ 
2984+ 	logBalance (t .t , nodes , assetID , "before multi-rfq receive" )
2985+ 
2986+ 	hodlInv  :=  createAssetHodlInvoice (t .t , nil , fabia , 20_000 , assetID )
2987+ 
2988+ 	payInvoiceWithSatoshi (
2989+ 		t .t , charlie , & lnrpc.AddInvoiceResponse {
2990+ 			PaymentRequest : hodlInv .payReq ,
2991+ 		},
2992+ 		withGroupKey (groupID ),
2993+ 		withFailure (lnrpc .Payment_IN_FLIGHT , failureNone ),
2994+ 	)
2995+ 
2996+ 	logBalance (t .t , nodes , assetID , "after inflight multi-rfq" )
2997+ 
2998+ 	// Assert that some HTLCs are present from Fabia's point of view. 
2999+ 	assertMinNumHtlcs (t .t , fabia , 1 )
3000+ 
3001+ 	// Assert that Charlie also has at least one outgoing HTLC as a sanity 
3002+ 	// check. 
3003+ 	assertMinNumHtlcs (t .t , charlie , 1 )
3004+ 
3005+ 	// Now let's cancel the invoice and assert that all inbound channels 
3006+ 	// have cleared their HTLCs. 
3007+ 	payHash  :=  hodlInv .preimage .Hash ()
3008+ 	_ , err  =  fabia .InvoicesClient .CancelInvoice (
3009+ 		ctx , & invoicesrpc.CancelInvoiceMsg {
3010+ 			PaymentHash : payHash [:],
3011+ 		},
3012+ 	)
3013+ 	require .NoError (t .t , err )
3014+ 
3015+ 	assertNumHtlcs (t .t , dave , 0 )
3016+ 	assertNumHtlcs (t .t , erin , 0 )
3017+ 	assertNumHtlcs (t .t , yara , 0 )
3018+ 
3019+ 	logBalance (t .t , nodes , assetID , "after cancelled hodl" )
3020+ 
3021+ 	// Now let's create a normal invoice that will be settled once all the 
3022+ 	// HTLCs have been received. This is only possible because the payer 
3023+ 	// uses multiple bolt11 hop hints to reach the destination. 
3024+ 	invoiceResp  :=  createAssetInvoice (t .t , nil , fabia , 15_000 , assetID )
3025+ 
3026+ 	payInvoiceWithSatoshi (
3027+ 		t .t , charlie , invoiceResp , withGroupKey (groupID ),
3028+ 	)
3029+ 
3030+ 	logBalance (t .t , nodes , assetID , "after multi-rfq receive" )
3031+ }
3032+ 
28953033// testCustomChannelsStrictForwarding is a test that tests the strict forwarding 
28963034// behavior of a node when it comes to paying asset invoices with assets and 
28973035// BTC invoices with satoshis. 
0 commit comments