@@ -77,25 +77,32 @@ type itestNode struct {
7777// multiRfqNodes contains all the itest nodes that are required to set up the
7878// multi RFQ network topology.
7979type multiRfqNodes struct {
80- charlie , dave , erin , fabia , yara itestNode
81- universeTap * tapClient
80+ charlie , dave , erin , fabia , yara , george itestNode
81+ universeTap * tapClient
8282}
8383
8484// createTestMultiRFQAssetNetwork creates a lightning network topology which
8585// consists of both bitcoin and asset channels. It focuses on the property of
8686// having multiple channels available on both the sender and receiver side.
87+ // The George node is using a way different oracle that provides asset rates
88+ // that fall outside of the configured tolerance bounds, leading to RFQ
89+ // negotiation failures.
8790//
8891// The topology we are going for looks like the following:
8992//
90- // /---[sats]--> Erin --[assets]--\
91- // / \
92- // / \
93+ // /---[sats]--> Erin --[assets]--\
94+ // / \
95+ // / \
96+ // / \
9397//
94- // Charlie -----[sats]--> Dave --[assets]----> Fabia
98+ // Charlie -----[sats]--> Dave --[assets]--> Fabia
9599//
96- // \ /
97- // \ /
98- // \---[sats]--> Yara --[assets]--/
100+ // \ / /
101+ // \ / /
102+ // \---[sats]--> Yara --[assets]-----/ /
103+ // \ /
104+ // \ /
105+ // \--[sats]-> George --[assets]-/
99106func createTestMultiRFQAssetNetwork (t * harnessTest , net * NetworkHarness ,
100107 nodes multiRfqNodes , mintedAsset * taprpc.Asset , assetSendAmount ,
101108 fundingAmount uint64 , pushSat int64 ) (* lnrpc.ChannelPoint ,
@@ -106,6 +113,7 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
106113 erin , erinTap := nodes .erin .Lnd , nodes .erin .Tapd
107114 _ , fabiaTap := nodes .fabia .Lnd , nodes .fabia .Tapd
108115 yara , yaraTap := nodes .yara .Lnd , nodes .yara .Tapd
116+ george , georgeTap := nodes .george .Lnd , nodes .george .Tapd
109117 universeTap := nodes .universeTap
110118
111119 // Let's open the normal sats channels between Charlie and the routing
@@ -131,6 +139,13 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
131139 },
132140 )
133141
142+ _ = openChannelAndAssert (
143+ t , net , charlie , george , lntest.OpenChannelParams {
144+ Amt : 10_000_000 ,
145+ SatPerVByte : 5 ,
146+ },
147+ )
148+
134149 ctxb := context .Background ()
135150 assetID := mintedAsset .AssetGenesis .AssetId
136151 var groupKey []byte
@@ -225,6 +240,34 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
225240 )
226241 itest .AssertNonInteractiveRecvComplete (t .t , yaraTap , 1 )
227242
243+ // We need to send some assets to George, so he can fund an asset
244+ // channel with Fabia.
245+ georgeAddr , err := georgeTap .NewAddr (ctxb , & taprpc.NewAddrRequest {
246+ Amt : assetSendAmount ,
247+ AssetId : assetID ,
248+ ProofCourierAddr : fmt .Sprintf (
249+ "%s://%s" , proof .UniverseRpcCourierType ,
250+ charlieTap .node .Cfg .LitAddr (),
251+ ),
252+ })
253+ require .NoError (t .t , err )
254+
255+ t .Logf ("Sending %v asset units to George..." , assetSendAmount )
256+
257+ // Send the assets to George.
258+ itest .AssertAddrCreated (t .t , georgeTap , mintedAsset , georgeAddr )
259+ sendResp , err = charlieTap .SendAsset (ctxb , & taprpc.SendAssetRequest {
260+ TapAddrs : []string {georgeAddr .Encoded },
261+ })
262+ require .NoError (t .t , err )
263+ itest .ConfirmAndAssertOutboundTransfer (
264+ t .t , t .lndHarness .Miner .Client , charlieTap , sendResp , assetID ,
265+ []uint64 {
266+ mintedAsset .Amount - 4 * assetSendAmount , assetSendAmount ,
267+ }, 3 , 4 ,
268+ )
269+ itest .AssertNonInteractiveRecvComplete (t .t , georgeTap , 1 )
270+
228271 // We fund the Dave->Fabia channel.
229272 fundRespDF , err := daveTap .FundChannel (
230273 ctxb , & tchrpc.FundChannelRequest {
@@ -264,6 +307,19 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
264307 require .NoError (t .t , err )
265308 t .Logf ("Funded channel between Yara and Fabia: %v" , fundRespYF )
266309
310+ // We fund the George->Fabia channel.
311+ fundRespGF , err := georgeTap .FundChannel (
312+ ctxb , & tchrpc.FundChannelRequest {
313+ AssetAmount : fundingAmount ,
314+ AssetId : assetID ,
315+ PeerPubkey : fabiaTap .node .PubKey [:],
316+ FeeRateSatPerVbyte : 5 ,
317+ PushSat : pushSat ,
318+ },
319+ )
320+ require .NoError (t .t , err )
321+ t .Logf ("Funded channel between George and Fabia: %v" , fundRespGF )
322+
267323 // Make sure the pending channel shows up in the list and has the
268324 // custom records set as JSON.
269325 assertPendingChannels (
@@ -275,17 +331,21 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
275331 assertPendingChannels (
276332 t .t , yaraTap .node , mintedAsset , 1 , fundingAmount , 0 ,
277333 )
334+ assertPendingChannels (
335+ t .t , georgeTap .node , mintedAsset , 1 , fundingAmount , 0 ,
336+ )
278337
279338 // Now that we've looked at the pending channels, let's actually confirm
280339 // all three of them.
281- mineBlocks (t , net , 6 , 3 )
340+ mineBlocks (t , net , 6 , 4 )
282341
283342 // We'll be tracking the expected asset balances throughout the test, so
284343 // we can assert it after each action.
285- charlieAssetBalance := mintedAsset .Amount - 3 * assetSendAmount
344+ charlieAssetBalance := mintedAsset .Amount - 4 * assetSendAmount
286345 daveAssetBalance := assetSendAmount - fundingAmount
287346 erinAssetBalance := assetSendAmount - fundingAmount
288347 yaraAssetBalance := assetSendAmount - fundingAmount
348+ georgeAssetBalance := assetSendAmount - fundingAmount
289349
290350 itest .AssertBalances (
291351 t .t , charlieTap , charlieAssetBalance ,
@@ -304,6 +364,10 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
304364 t .t , yaraTap , yaraAssetBalance , itest .WithAssetID (assetID ),
305365 )
306366
367+ itest .AssertBalances (
368+ t .t , georgeTap , georgeAssetBalance , itest .WithAssetID (assetID ),
369+ )
370+
307371 // Assert that the proofs for both channels has been uploaded to the
308372 // designated Universe server.
309373 assertUniverseProofExists (
@@ -318,6 +382,10 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
318382 t .t , universeTap , assetID , groupKey , fundingScriptTreeBytes ,
319383 fmt .Sprintf ("%v:%v" , fundRespYF .Txid , fundRespYF .OutputIndex ),
320384 )
385+ assertUniverseProofExists (
386+ t .t , universeTap , assetID , groupKey , fundingScriptTreeBytes ,
387+ fmt .Sprintf ("%v:%v" , fundRespGF .Txid , fundRespGF .OutputIndex ),
388+ )
321389
322390 return nil , nil , nil
323391}
@@ -1355,7 +1423,7 @@ func sendAssetKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64,
13551423 return
13561424 }
13571425
1358- result , err := getAssetPaymentResult (stream , false )
1426+ result , _ , err := getAssetPaymentResult (t , stream , false )
13591427 require .NoError (t , err )
13601428 if result .Status == lnrpc .Payment_FAILED {
13611429 t .Logf ("Failure reason: %v" , result .FailureReason )
@@ -1687,14 +1755,18 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
16871755 sendReq .MaxShardSizeMsat = 80_000_000
16881756 }
16891757
1690- var rfqBytes []byte
1758+ var rfqBytes , peerPubKey []byte
16911759 cfg .rfq .WhenSome (func (i rfqmsg.ID ) {
16921760 rfqBytes = make ([]byte , len (i [:]))
16931761 copy (rfqBytes , i [:])
16941762 })
16951763
1764+ if rfqPeer != nil {
1765+ peerPubKey = rfqPeer .PubKey [:]
1766+ }
1767+
16961768 request := & tchrpc.SendPaymentRequest {
1697- PeerPubkey : rfqPeer . PubKey [:] ,
1769+ PeerPubkey : peerPubKey ,
16981770 PaymentRequest : sendReq ,
16991771 RfqId : rfqBytes ,
17001772 AllowOverpay : cfg .allowOverpay ,
@@ -1715,7 +1787,13 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
17151787 // was established, no network or auth error), we expect the error to be
17161788 // returned on the first read on the stream.
17171789 if cfg .errSubStr != "" {
1718- _ , err := stream .Recv ()
1790+ msg , err := stream .Recv ()
1791+
1792+ // On errors we still get an empty set of RFQs as a response.
1793+ if msg .GetAcceptedSellOrders () != nil {
1794+ _ , err = stream .Recv ()
1795+ }
1796+
17191797 require .ErrorContains (t , err , cfg .errSubStr )
17201798
17211799 return 0 , rfqmath.BigIntFixedPoint {}
@@ -1725,42 +1803,18 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
17251803 numUnits uint64
17261804 rateVal rfqmath.FixedPoint [rfqmath.BigInt ]
17271805 )
1728- if cfg .rfq .IsNone () {
1729- // We want to receive the accepted quote message first, so we
1730- // know how many assets we're going to pay.
1731- quoteMsg , err := stream .Recv ()
1732- require .NoError (t , err )
1733- acceptedQuote := quoteMsg .GetAcceptedSellOrder ()
1734- require .NotNil (t , acceptedQuote )
1735-
1736- peerPubKey := acceptedQuote .Peer
1737- require .Equal (t , peerPubKey , rfqPeer .PubKeyStr )
1738-
1739- rpcRate := acceptedQuote .BidAssetRate
1740- rate , err := rpcutils .UnmarshalRfqFixedPoint (rpcRate )
1741- require .NoError (t , err )
1742-
1743- rateVal = * rate
17441806
1745- t .Logf ("Got quote for %v asset units per BTC" , rate )
1746-
1747- amountMsat := lnwire .MilliSatoshi (decodedInvoice .NumMsat )
1748- milliSatsFP := rfqmath .MilliSatoshiToUnits (amountMsat , * rate )
1749- numUnits = milliSatsFP .ScaleTo (0 ).ToUint64 ()
1750- msatPerUnit := float64 (decodedInvoice .NumMsat ) /
1751- float64 (numUnits )
1752- t .Logf ("Got quote for %v asset units at %3f msat/unit from " +
1753- "peer %s with SCID %d" , numUnits , msatPerUnit ,
1754- peerPubKey , acceptedQuote .Scid )
1755- }
1756-
1757- result , err := getAssetPaymentResult (
1758- stream , cfg .payStatus == lnrpc .Payment_IN_FLIGHT ,
1807+ result , rateVal , err := getAssetPaymentResult (
1808+ t , stream , cfg .payStatus == lnrpc .Payment_IN_FLIGHT ,
17591809 )
17601810 require .NoError (t , err )
17611811 require .Equal (t , cfg .payStatus , result .Status )
17621812 require .Equal (t , cfg .failureReason , result .FailureReason )
17631813
1814+ amountMsat := lnwire .MilliSatoshi (decodedInvoice .NumMsat )
1815+ milliSatsFP := rfqmath .MilliSatoshiToUnits (amountMsat , rateVal )
1816+ numUnits = milliSatsFP .ScaleTo (0 ).ToUint64 ()
1817+
17641818 return numUnits , rateVal
17651819}
17661820
0 commit comments