@@ -77,25 +77,32 @@ type itestNode struct {
77
77
// multiRfqNodes contains all the itest nodes that are required to set up the
78
78
// multi RFQ network topology.
79
79
type multiRfqNodes struct {
80
- charlie , dave , erin , fabia , yara itestNode
81
- universeTap * tapClient
80
+ charlie , dave , erin , fabia , yara , george itestNode
81
+ universeTap * tapClient
82
82
}
83
83
84
84
// createTestMultiRFQAssetNetwork creates a lightning network topology which
85
85
// consists of both bitcoin and asset channels. It focuses on the property of
86
86
// 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.
87
90
//
88
91
// The topology we are going for looks like the following:
89
92
//
90
- // /---[sats]--> Erin --[assets]--\
91
- // / \
92
- // / \
93
+ // /---[sats]--> Erin --[assets]--\
94
+ // / \
95
+ // / \
96
+ // / \
93
97
//
94
- // Charlie -----[sats]--> Dave --[assets]----> Fabia
98
+ // Charlie -----[sats]--> Dave --[assets]--> Fabia
95
99
//
96
- // \ /
97
- // \ /
98
- // \---[sats]--> Yara --[assets]--/
100
+ // \ / /
101
+ // \ / /
102
+ // \---[sats]--> Yara --[assets]-----/ /
103
+ // \ /
104
+ // \ /
105
+ // \--[sats]-> George --[assets]-/
99
106
func createTestMultiRFQAssetNetwork (t * harnessTest , net * NetworkHarness ,
100
107
nodes multiRfqNodes , mintedAsset * taprpc.Asset , assetSendAmount ,
101
108
fundingAmount uint64 , pushSat int64 ) (* lnrpc.ChannelPoint ,
@@ -106,6 +113,7 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
106
113
erin , erinTap := nodes .erin .Lnd , nodes .erin .Tapd
107
114
_ , fabiaTap := nodes .fabia .Lnd , nodes .fabia .Tapd
108
115
yara , yaraTap := nodes .yara .Lnd , nodes .yara .Tapd
116
+ george , georgeTap := nodes .george .Lnd , nodes .george .Tapd
109
117
universeTap := nodes .universeTap
110
118
111
119
// Let's open the normal sats channels between Charlie and the routing
@@ -131,6 +139,13 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
131
139
},
132
140
)
133
141
142
+ _ = openChannelAndAssert (
143
+ t , net , charlie , george , lntest.OpenChannelParams {
144
+ Amt : 10_000_000 ,
145
+ SatPerVByte : 5 ,
146
+ },
147
+ )
148
+
134
149
ctxb := context .Background ()
135
150
assetID := mintedAsset .AssetGenesis .AssetId
136
151
var groupKey []byte
@@ -225,6 +240,34 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
225
240
)
226
241
itest .AssertNonInteractiveRecvComplete (t .t , yaraTap , 1 )
227
242
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
+
228
271
// We fund the Dave->Fabia channel.
229
272
fundRespDF , err := daveTap .FundChannel (
230
273
ctxb , & tchrpc.FundChannelRequest {
@@ -264,6 +307,19 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
264
307
require .NoError (t .t , err )
265
308
t .Logf ("Funded channel between Yara and Fabia: %v" , fundRespYF )
266
309
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
+
267
323
// Make sure the pending channel shows up in the list and has the
268
324
// custom records set as JSON.
269
325
assertPendingChannels (
@@ -275,17 +331,21 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
275
331
assertPendingChannels (
276
332
t .t , yaraTap .node , mintedAsset , 1 , fundingAmount , 0 ,
277
333
)
334
+ assertPendingChannels (
335
+ t .t , georgeTap .node , mintedAsset , 1 , fundingAmount , 0 ,
336
+ )
278
337
279
338
// Now that we've looked at the pending channels, let's actually confirm
280
339
// all three of them.
281
- mineBlocks (t , net , 6 , 3 )
340
+ mineBlocks (t , net , 6 , 4 )
282
341
283
342
// We'll be tracking the expected asset balances throughout the test, so
284
343
// we can assert it after each action.
285
- charlieAssetBalance := mintedAsset .Amount - 3 * assetSendAmount
344
+ charlieAssetBalance := mintedAsset .Amount - 4 * assetSendAmount
286
345
daveAssetBalance := assetSendAmount - fundingAmount
287
346
erinAssetBalance := assetSendAmount - fundingAmount
288
347
yaraAssetBalance := assetSendAmount - fundingAmount
348
+ georgeAssetBalance := assetSendAmount - fundingAmount
289
349
290
350
itest .AssertBalances (
291
351
t .t , charlieTap , charlieAssetBalance ,
@@ -304,6 +364,10 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
304
364
t .t , yaraTap , yaraAssetBalance , itest .WithAssetID (assetID ),
305
365
)
306
366
367
+ itest .AssertBalances (
368
+ t .t , georgeTap , georgeAssetBalance , itest .WithAssetID (assetID ),
369
+ )
370
+
307
371
// Assert that the proofs for both channels has been uploaded to the
308
372
// designated Universe server.
309
373
assertUniverseProofExists (
@@ -318,6 +382,10 @@ func createTestMultiRFQAssetNetwork(t *harnessTest, net *NetworkHarness,
318
382
t .t , universeTap , assetID , groupKey , fundingScriptTreeBytes ,
319
383
fmt .Sprintf ("%v:%v" , fundRespYF .Txid , fundRespYF .OutputIndex ),
320
384
)
385
+ assertUniverseProofExists (
386
+ t .t , universeTap , assetID , groupKey , fundingScriptTreeBytes ,
387
+ fmt .Sprintf ("%v:%v" , fundRespGF .Txid , fundRespGF .OutputIndex ),
388
+ )
321
389
322
390
return nil , nil , nil
323
391
}
@@ -1355,7 +1423,7 @@ func sendAssetKeySendPayment(t *testing.T, src, dst *HarnessNode, amt uint64,
1355
1423
return
1356
1424
}
1357
1425
1358
- result , err := getAssetPaymentResult (stream , false )
1426
+ result , _ , err := getAssetPaymentResult (t , stream , false )
1359
1427
require .NoError (t , err )
1360
1428
if result .Status == lnrpc .Payment_FAILED {
1361
1429
t .Logf ("Failure reason: %v" , result .FailureReason )
@@ -1687,14 +1755,18 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
1687
1755
sendReq .MaxShardSizeMsat = 80_000_000
1688
1756
}
1689
1757
1690
- var rfqBytes []byte
1758
+ var rfqBytes , peerPubKey []byte
1691
1759
cfg .rfq .WhenSome (func (i rfqmsg.ID ) {
1692
1760
rfqBytes = make ([]byte , len (i [:]))
1693
1761
copy (rfqBytes , i [:])
1694
1762
})
1695
1763
1764
+ if rfqPeer != nil {
1765
+ peerPubKey = rfqPeer .PubKey [:]
1766
+ }
1767
+
1696
1768
request := & tchrpc.SendPaymentRequest {
1697
- PeerPubkey : rfqPeer . PubKey [:] ,
1769
+ PeerPubkey : peerPubKey ,
1698
1770
PaymentRequest : sendReq ,
1699
1771
RfqId : rfqBytes ,
1700
1772
AllowOverpay : cfg .allowOverpay ,
@@ -1715,7 +1787,13 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
1715
1787
// was established, no network or auth error), we expect the error to be
1716
1788
// returned on the first read on the stream.
1717
1789
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
+
1719
1797
require .ErrorContains (t , err , cfg .errSubStr )
1720
1798
1721
1799
return 0 , rfqmath.BigIntFixedPoint {}
@@ -1725,42 +1803,18 @@ func payInvoiceWithAssets(t *testing.T, payer, rfqPeer *HarnessNode,
1725
1803
numUnits uint64
1726
1804
rateVal rfqmath.FixedPoint [rfqmath.BigInt ]
1727
1805
)
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
1744
1806
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 ,
1759
1809
)
1760
1810
require .NoError (t , err )
1761
1811
require .Equal (t , cfg .payStatus , result .Status )
1762
1812
require .Equal (t , cfg .failureReason , result .FailureReason )
1763
1813
1814
+ amountMsat := lnwire .MilliSatoshi (decodedInvoice .NumMsat )
1815
+ milliSatsFP := rfqmath .MilliSatoshiToUnits (amountMsat , rateVal )
1816
+ numUnits = milliSatsFP .ScaleTo (0 ).ToUint64 ()
1817
+
1764
1818
return numUnits , rateVal
1765
1819
}
1766
1820
0 commit comments