@@ -14,6 +14,7 @@ import (
1414 "github.com/lightningnetwork/lnd/lntypes"
1515 "github.com/lightningnetwork/lnd/lnwire"
1616 "github.com/lightningnetwork/lnd/routing/route"
17+ "github.com/stretchr/testify/require"
1718)
1819
1920// TestAutoLoopDisabled tests the case where we need to perform a swap, but
@@ -307,6 +308,156 @@ func TestAutoLoopEnabled(t *testing.T) {
307308 c .stop ()
308309}
309310
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+
310461// TestCompositeRules tests the case where we have rules set on a per peer
311462// and per channel basis, and perform swaps for both targets.
312463func TestCompositeRules (t * testing.T ) {
0 commit comments