|
|
|
@ -195,6 +195,7 @@ func newLoopOutSwap(globalCtx context.Context, cfg *swapConfig,
|
|
|
|
|
ProtocolVersion: loopdb.CurrentProtocolVersion(),
|
|
|
|
|
},
|
|
|
|
|
OutgoingChanSet: chanSet,
|
|
|
|
|
PaymentTimeout: request.PaymentTimeout,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
swapKit := newSwapKit(
|
|
|
|
@ -610,7 +611,8 @@ func (s *loopOutSwap) payInvoices(ctx context.Context) {
|
|
|
|
|
// Use the recommended routing plugin.
|
|
|
|
|
s.swapPaymentChan = s.payInvoice(
|
|
|
|
|
ctx, s.SwapInvoice, s.MaxSwapRoutingFee,
|
|
|
|
|
s.LoopOutContract.OutgoingChanSet, pluginType, true,
|
|
|
|
|
s.LoopOutContract.OutgoingChanSet,
|
|
|
|
|
s.LoopOutContract.PaymentTimeout, pluginType, true,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// Pay the prepay invoice. Won't use the routing plugin here as the
|
|
|
|
@ -619,7 +621,8 @@ func (s *loopOutSwap) payInvoices(ctx context.Context) {
|
|
|
|
|
s.log.Infof("Sending prepayment %v", s.PrepayInvoice)
|
|
|
|
|
s.prePaymentChan = s.payInvoice(
|
|
|
|
|
ctx, s.PrepayInvoice, s.MaxPrepayRoutingFee,
|
|
|
|
|
s.LoopOutContract.OutgoingChanSet, RoutingPluginNone, false,
|
|
|
|
|
s.LoopOutContract.OutgoingChanSet,
|
|
|
|
|
s.LoopOutContract.PaymentTimeout, RoutingPluginNone, false,
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -647,7 +650,7 @@ func (p paymentResult) failure() error {
|
|
|
|
|
// payInvoice pays a single invoice.
|
|
|
|
|
func (s *loopOutSwap) payInvoice(ctx context.Context, invoice string,
|
|
|
|
|
maxFee btcutil.Amount, outgoingChanIds loopdb.ChannelSet,
|
|
|
|
|
pluginType RoutingPluginType,
|
|
|
|
|
paymentTimeout time.Duration, pluginType RoutingPluginType,
|
|
|
|
|
reportPluginResult bool) chan paymentResult {
|
|
|
|
|
|
|
|
|
|
resultChan := make(chan paymentResult)
|
|
|
|
@ -662,8 +665,8 @@ func (s *loopOutSwap) payInvoice(ctx context.Context, invoice string,
|
|
|
|
|
var result paymentResult
|
|
|
|
|
|
|
|
|
|
status, err := s.payInvoiceAsync(
|
|
|
|
|
ctx, invoice, maxFee, outgoingChanIds, pluginType,
|
|
|
|
|
reportPluginResult,
|
|
|
|
|
ctx, invoice, maxFee, outgoingChanIds, paymentTimeout,
|
|
|
|
|
pluginType, reportPluginResult,
|
|
|
|
|
)
|
|
|
|
|
if err != nil {
|
|
|
|
|
result.err = err
|
|
|
|
@ -691,8 +694,9 @@ func (s *loopOutSwap) payInvoice(ctx context.Context, invoice string,
|
|
|
|
|
// payInvoiceAsync is the asynchronously executed part of paying an invoice.
|
|
|
|
|
func (s *loopOutSwap) payInvoiceAsync(ctx context.Context,
|
|
|
|
|
invoice string, maxFee btcutil.Amount,
|
|
|
|
|
outgoingChanIds loopdb.ChannelSet, pluginType RoutingPluginType,
|
|
|
|
|
reportPluginResult bool) (*lndclient.PaymentStatus, error) {
|
|
|
|
|
outgoingChanIds loopdb.ChannelSet, paymentTimeout time.Duration,
|
|
|
|
|
pluginType RoutingPluginType, reportPluginResult bool) (
|
|
|
|
|
*lndclient.PaymentStatus, error) {
|
|
|
|
|
|
|
|
|
|
// Extract hash from payment request. Unfortunately the request
|
|
|
|
|
// components aren't available directly.
|
|
|
|
@ -705,7 +709,7 @@ func (s *loopOutSwap) payInvoiceAsync(ctx context.Context,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
maxRetries := 1
|
|
|
|
|
paymentTimeout := s.executeConfig.totalPaymentTimeout
|
|
|
|
|
totalPaymentTimeout := s.executeConfig.totalPaymentTimeout
|
|
|
|
|
|
|
|
|
|
// Attempt to acquire and initialize the routing plugin.
|
|
|
|
|
routingPlugin, err := AcquireRoutingPlugin(
|
|
|
|
@ -720,8 +724,30 @@ func (s *loopOutSwap) payInvoiceAsync(ctx context.Context,
|
|
|
|
|
pluginType, hash.String())
|
|
|
|
|
|
|
|
|
|
maxRetries = s.executeConfig.maxPaymentRetries
|
|
|
|
|
paymentTimeout /= time.Duration(maxRetries)
|
|
|
|
|
|
|
|
|
|
// If not set, default to the per payment timeout to the total
|
|
|
|
|
// payment timeout divied by the configured maximum retries.
|
|
|
|
|
if paymentTimeout == 0 {
|
|
|
|
|
paymentTimeout = totalPaymentTimeout /
|
|
|
|
|
time.Duration(maxRetries)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If the payment timeout is too long, we need to adjust the
|
|
|
|
|
// number of retries to ensure we don't exceed the total
|
|
|
|
|
// payment timeout.
|
|
|
|
|
if paymentTimeout*time.Duration(maxRetries) >
|
|
|
|
|
totalPaymentTimeout {
|
|
|
|
|
|
|
|
|
|
maxRetries = int(totalPaymentTimeout / paymentTimeout)
|
|
|
|
|
s.log.Infof("Adjusted max routing plugin retries to "+
|
|
|
|
|
"%v to stay within total payment timeout",
|
|
|
|
|
maxRetries)
|
|
|
|
|
}
|
|
|
|
|
defer ReleaseRoutingPlugin(ctx)
|
|
|
|
|
} else if paymentTimeout == 0 {
|
|
|
|
|
// If not set, default the payment timeout to the total payment
|
|
|
|
|
// timeout.
|
|
|
|
|
paymentTimeout = totalPaymentTimeout
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
req := lndclient.SendPaymentRequest{
|
|
|
|
|