@@ -14,6 +14,7 @@ import (
14
14
"github.com/lightningnetwork/lnd/lntypes"
15
15
"github.com/lightningnetwork/lnd/lnwire"
16
16
"github.com/lightningnetwork/lnd/routing/route"
17
+ "github.com/stretchr/testify/require"
17
18
)
18
19
19
20
// TestAutoLoopDisabled tests the case where we need to perform a swap, but
@@ -307,6 +308,156 @@ func TestAutoLoopEnabled(t *testing.T) {
307
308
c .stop ()
308
309
}
309
310
311
+ // TestAutoloopAddress tests that the custom destination address feature for
312
+ // loop out behaves as expected.
313
+ func TestAutoloopAddress (t * testing.T ) {
314
+ defer test .Guard (t )()
315
+
316
+ // Decode a dummy p2wkh address to use as the destination address for
317
+ // the swaps.
318
+ p2wkhAddr := "bcrt1qq68r6ff4k4pjx39efs44gcyccf7unqnu5qtjjz"
319
+ addr , err := btcutil .DecodeAddress (p2wkhAddr , nil )
320
+ if err != nil {
321
+ t .Error (err )
322
+ }
323
+
324
+ var (
325
+ channels = []lndclient.ChannelInfo {
326
+ channel1 , channel2 ,
327
+ }
328
+
329
+ swapFeePPM uint64 = 1000
330
+ routeFeePPM uint64 = 1000
331
+ prepayFeePPM uint64 = 1000
332
+ prepayAmount = btcutil .Amount (20000 )
333
+ maxMiner = btcutil .Amount (20000 )
334
+
335
+ // Create some dummy parameters for autoloop and also specify an
336
+ // destination address.
337
+ params = Parameters {
338
+ Autoloop : true ,
339
+ AutoFeeBudget : 40066 ,
340
+ DestAddr : addr ,
341
+ AutoFeeStartDate : testTime ,
342
+ MaxAutoInFlight : 2 ,
343
+ FailureBackOff : time .Hour ,
344
+ SweepConfTarget : 10 ,
345
+ FeeLimit : NewFeeCategoryLimit (
346
+ swapFeePPM , routeFeePPM , prepayFeePPM , maxMiner ,
347
+ prepayAmount , 20000 ,
348
+ ),
349
+ ChannelRules : map [lnwire.ShortChannelID ]* SwapRule {
350
+ chanID1 : chanRule ,
351
+ chanID2 : chanRule ,
352
+ },
353
+ HtlcConfTarget : defaultHtlcConfTarget ,
354
+ }
355
+ )
356
+ c := newAutoloopTestCtx (t , params , channels , testRestrictions )
357
+ c .start ()
358
+
359
+ // Get parameters from manager and verify that address is set correctly.
360
+ params = c .manager .GetParameters ()
361
+ require .Equal (t , params .DestAddr , addr )
362
+
363
+ // Calculate our maximum allowed fees and create quotes that fall within
364
+ // our budget.
365
+ var (
366
+ amt = chan1Rec .Amount
367
+
368
+ maxSwapFee = ppmToSat (amt , swapFeePPM )
369
+
370
+ quote1 = & loop.LoopOutQuote {
371
+ SwapFee : maxSwapFee ,
372
+ PrepayAmount : prepayAmount - 10 ,
373
+ MinerFee : maxMiner - 10 ,
374
+ }
375
+
376
+ quote2 = & loop.LoopOutQuote {
377
+ SwapFee : maxSwapFee ,
378
+ PrepayAmount : prepayAmount - 20 ,
379
+ MinerFee : maxMiner - 10 ,
380
+ }
381
+
382
+ quoteRequest = & loop.LoopOutQuoteRequest {
383
+ Amount : amt ,
384
+ SweepConfTarget : params .SweepConfTarget ,
385
+ }
386
+
387
+ quotes = []quoteRequestResp {
388
+ {
389
+ request : quoteRequest ,
390
+ quote : quote1 ,
391
+ },
392
+ {
393
+ request : quoteRequest ,
394
+ quote : quote2 ,
395
+ },
396
+ }
397
+
398
+ maxRouteFee = ppmToSat (amt , routeFeePPM )
399
+
400
+ chan1Swap = & loop.OutRequest {
401
+ Amount : amt ,
402
+ // Define the expected destination address.
403
+ DestAddr : addr ,
404
+ MaxSwapRoutingFee : maxRouteFee ,
405
+ MaxPrepayRoutingFee : ppmToSat (
406
+ quote1 .PrepayAmount , prepayFeePPM ,
407
+ ),
408
+ MaxSwapFee : quote1 .SwapFee ,
409
+ MaxPrepayAmount : quote1 .PrepayAmount ,
410
+ MaxMinerFee : maxMiner ,
411
+ SweepConfTarget : params .SweepConfTarget ,
412
+ OutgoingChanSet : loopdb.ChannelSet {chanID1 .ToUint64 ()},
413
+ Label : labels .AutoloopLabel (swap .TypeOut ),
414
+ Initiator : autoloopSwapInitiator ,
415
+ }
416
+
417
+ chan2Swap = & loop.OutRequest {
418
+ Amount : amt ,
419
+ // Define the expected destination address.
420
+ DestAddr : addr ,
421
+ MaxSwapRoutingFee : maxRouteFee ,
422
+ MaxPrepayRoutingFee : ppmToSat (
423
+ quote2 .PrepayAmount , routeFeePPM ,
424
+ ),
425
+ MaxSwapFee : quote2 .SwapFee ,
426
+ MaxPrepayAmount : quote2 .PrepayAmount ,
427
+ MaxMinerFee : maxMiner ,
428
+ SweepConfTarget : params .SweepConfTarget ,
429
+ OutgoingChanSet : loopdb.ChannelSet {chanID2 .ToUint64 ()},
430
+ Label : labels .AutoloopLabel (swap .TypeOut ),
431
+ Initiator : autoloopSwapInitiator ,
432
+ }
433
+
434
+ loopOuts = []loopOutRequestResp {
435
+ {
436
+ request : chan1Swap ,
437
+ response : & loop.LoopOutSwapInfo {
438
+ SwapHash : lntypes.Hash {1 },
439
+ },
440
+ },
441
+ {
442
+ request : chan2Swap ,
443
+ response : & loop.LoopOutSwapInfo {
444
+ SwapHash : lntypes.Hash {2 },
445
+ },
446
+ },
447
+ }
448
+ )
449
+
450
+ step := & autoloopStep {
451
+ minAmt : 1 ,
452
+ maxAmt : amt + 1 ,
453
+ quotesOut : quotes ,
454
+ expectedOut : loopOuts ,
455
+ }
456
+ c .autoloop (step )
457
+
458
+ c .stop ()
459
+ }
460
+
310
461
// TestCompositeRules tests the case where we have rules set on a per peer
311
462
// and per channel basis, and perform swaps for both targets.
312
463
func TestCompositeRules (t * testing.T ) {
0 commit comments