@@ -2147,3 +2147,133 @@ func testCustomChannelsBalanceConsistency(_ context.Context,
21472147	assertNumAssetOutputs (t .t , charlieTap , assetID , 1 )
21482148	assertNumAssetOutputs (t .t , daveTap , assetID , 1 )
21492149}
2150+ 
2151+ // testCustomChannelsMultiInput tests whether it is possible to fund a channel 
2152+ // using FundChannel that uses multiple inputs from the same asset. 
2153+ func  testCustomChannelsMultiInput (_  context.Context , net  * NetworkHarness ,
2154+ 	t  * harnessTest ) {
2155+ 
2156+ 	ctxb  :=  context .Background ()
2157+ 	lndArgs  :=  slices .Clone (lndArgsTemplate )
2158+ 	litdArgs  :=  slices .Clone (litdArgsTemplate )
2159+ 
2160+ 	zane , err  :=  net .NewNode (
2161+ 		t .t , "Zane" , lndArgs , false , true , litdArgs ... ,
2162+ 	)
2163+ 	require .NoError (t .t , err )
2164+ 
2165+ 	litdArgs  =  append (litdArgs , fmt .Sprintf (
2166+ 		"--taproot-assets.proofcourieraddr=%s://%s" ,
2167+ 		proof .UniverseRpcCourierType , zane .Cfg .LitAddr (),
2168+ 	))
2169+ 
2170+ 	charlie , err  :=  net .NewNode (
2171+ 		t .t , "Charlie" , lndArgs , false , true , litdArgs ... ,
2172+ 	)
2173+ 	require .NoError (t .t , err )
2174+ 	dave , err  :=  net .NewNode (t .t , "Dave" , lndArgs , false , true , litdArgs ... )
2175+ 	require .NoError (t .t , err )
2176+ 
2177+ 	nodes  :=  []* HarnessNode {charlie , dave }
2178+ 	connectAllNodes (t .t , net , nodes )
2179+ 	fundAllNodes (t .t , net , nodes )
2180+ 
2181+ 	charlieTap  :=  newTapClient (t .t , charlie )
2182+ 	daveTap  :=  newTapClient (t .t , dave )
2183+ 
2184+ 	// Mint an assets on Charlie and sync Dave to Charlie as the universe. 
2185+ 	mintedAssets  :=  itest .MintAssetsConfirmBatch (
2186+ 		t .t , t .lndHarness .Miner .Client , charlieTap ,
2187+ 		[]* mintrpc.MintAssetRequest {
2188+ 			{
2189+ 				Asset : itestAsset ,
2190+ 			},
2191+ 		},
2192+ 	)
2193+ 	cents  :=  mintedAssets [0 ]
2194+ 	assetID  :=  cents .AssetGenesis .AssetId 
2195+ 
2196+ 	t .Logf ("Minted %d lightning cents, syncing universes..." ,
2197+ 		cents .Amount )
2198+ 	syncUniverses (t .t , charlieTap , dave )
2199+ 	t .Logf ("Universes synced between all nodes, distributing assets..." )
2200+ 
2201+ 	// Charlie should have two balance outputs with the full balance. 
2202+ 	assertAssetBalance (t .t , charlieTap , assetID , cents .Amount )
2203+ 
2204+ 	// Send assets to Dave so he can fund a channel. 
2205+ 	halfCentsAmount  :=  cents .Amount  /  2 
2206+ 	daveAddr1 , err  :=  daveTap .NewAddr (ctxb , & taprpc.NewAddrRequest {
2207+ 		Amt :     halfCentsAmount ,
2208+ 		AssetId : assetID ,
2209+ 		ProofCourierAddr : fmt .Sprintf (
2210+ 			"%s://%s" , proof .UniverseRpcCourierType ,
2211+ 			charlieTap .node .Cfg .LitAddr (),
2212+ 		),
2213+ 	})
2214+ 	require .NoError (t .t , err )
2215+ 	daveAddr2 , err  :=  daveTap .NewAddr (ctxb , & taprpc.NewAddrRequest {
2216+ 		Amt :     halfCentsAmount ,
2217+ 		AssetId : assetID ,
2218+ 		ProofCourierAddr : fmt .Sprintf (
2219+ 			"%s://%s" , proof .UniverseRpcCourierType ,
2220+ 			charlieTap .node .Cfg .LitAddr (),
2221+ 		),
2222+ 	})
2223+ 	require .NoError (t .t , err )
2224+ 
2225+ 	t .Logf ("Sending %v asset units to Dave twice..." , halfCentsAmount )
2226+ 
2227+ 	// Send the first asset to Dave. 
2228+ 	itest .AssertAddrCreated (t .t , daveTap , cents , daveAddr1 )
2229+ 	sendResp , err  :=  charlieTap .SendAsset (ctxb , & taprpc.SendAssetRequest {
2230+ 		TapAddrs : []string {daveAddr1 .Encoded },
2231+ 	})
2232+ 	require .NoError (t .t , err )
2233+ 	itest .ConfirmAndAssertOutboundTransfer (
2234+ 		t .t , t .lndHarness .Miner .Client , charlieTap , sendResp , assetID ,
2235+ 		[]uint64 {cents .Amount  -  halfCentsAmount , halfCentsAmount },
2236+ 		0 , 1 ,
2237+ 	)
2238+ 	itest .AssertNonInteractiveRecvComplete (t .t , daveTap , 1 )
2239+ 
2240+ 	// Send the second asset to Dave. 
2241+ 	itest .AssertAddrCreated (t .t , daveTap , cents , daveAddr2 )
2242+ 	sendResp , err  =  charlieTap .SendAsset (ctxb , & taprpc.SendAssetRequest {
2243+ 		TapAddrs : []string {daveAddr2 .Encoded },
2244+ 	})
2245+ 	require .NoError (t .t , err )
2246+ 	itest .ConfirmAndAssertOutboundTransfer (
2247+ 		t .t , t .lndHarness .Miner .Client , charlieTap , sendResp , assetID ,
2248+ 		[]uint64 {cents .Amount  -  2 * halfCentsAmount , halfCentsAmount },
2249+ 		1 , 2 ,
2250+ 	)
2251+ 	itest .AssertNonInteractiveRecvComplete (t .t , daveTap , 2 )
2252+ 
2253+ 	// Fund a channel using multiple inputs from the same asset. 
2254+ 	fundRespCD , err  :=  daveTap .FundChannel (
2255+ 		ctxb , & tchrpc.FundChannelRequest {
2256+ 			AssetAmount :        2  *  halfCentsAmount ,
2257+ 			AssetId :            assetID ,
2258+ 			PeerPubkey :         charlieTap .node .PubKey [:],
2259+ 			FeeRateSatPerVbyte : 5 ,
2260+ 			PushSat :            0 ,
2261+ 		},
2262+ 	)
2263+ 	require .NoError (t .t , err )
2264+ 	t .Logf ("Funded channel between Charlie and Dave: %v" , fundRespCD )
2265+ 
2266+ 	// Let's confirm the channel. 
2267+ 	mineBlocks (t , net , 6 , 1 )
2268+ 
2269+ 	// Tapd should not report any balance for Charlie, since the asset is 
2270+ 	// used in a funding transaction. It should also not report any balance 
2271+ 	// for Dave. All those balances are reported through channel balances. 
2272+ 	assertAssetBalance (t .t , charlieTap , assetID , 0 )
2273+ 	assertAssetBalance (t .t , daveTap , assetID , 0 )
2274+ 
2275+ 	// Make sure the channel shows the correct asset information. 
2276+ 	assertAssetChan (
2277+ 		t .t , charlieTap .node , daveTap .node , 2 * halfCentsAmount , assetID ,
2278+ 	)
2279+ }
0 commit comments