routing/router: move sending and receiving payment result into loop

This commit is contained in:
Johan T. Halseth 2019-05-23 20:05:29 +02:00
parent 59c2557cc9
commit ae7bf2cb7b
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26

@ -1513,6 +1513,7 @@ type LightningPayment struct {
// when we should should abandon the payment attempt after consecutive
// payment failure. This prevents us from attempting to send a payment
// indefinitely.
// TODO(halseth): make wallclock time to allow resume after startup.
PayAttemptTimeout time.Duration
// RouteHints represents the different routing hints that can be used to
@ -1617,6 +1618,8 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
timeoutChan := time.After(payAttemptTimeout)
paymentHash := payment.PaymentHash
// We'll continue until either our payment succeeds, or we encounter a
// critical error during path finding.
var lastError error
@ -1657,26 +1660,6 @@ func (r *ChannelRouter) sendPayment(payment *LightningPayment,
return [32]byte{}, nil, err
}
// Send payment attempt. It will return a final boolean
// indicating if more attempts are needed.
preimage, final, err := r.sendPaymentAttempt(
paySession, route, payment.PaymentHash,
)
if final {
return preimage, route, err
}
lastError = err
}
}
// sendPaymentAttempt tries to send the payment via the specified route. If
// successful, it returns the obtained preimage. If an error occurs, the last
// bool parameter indicates whether this is a final outcome or more attempts
// should be made.
func (r *ChannelRouter) sendPaymentAttempt(paySession *paymentSession,
route *route.Route, paymentHash [32]byte) ([32]byte, bool, error) {
log.Tracef("Attempting to send payment %x, using route: %v",
paymentHash, newLogClosure(func() string {
return spew.Sdump(route)
@ -1686,8 +1669,9 @@ func (r *ChannelRouter) sendPaymentAttempt(paySession *paymentSession,
// Generate a new key to be used for this attempt.
sessionKey, err := generateNewSessionKey()
if err != nil {
return [32]byte{}, true, err
return [32]byte{}, nil, err
}
// Generate the raw encoded sphinx packet to be included along
// with the htlcAdd message that we send directly to the
// switch.
@ -1695,7 +1679,7 @@ func (r *ChannelRouter) sendPaymentAttempt(paySession *paymentSession,
route, paymentHash[:], sessionKey,
)
if err != nil {
return [32]byte{}, true, err
return [32]byte{}, nil, err
}
// Craft an HTLC packet to send to the layer 2 switch. The
@ -1719,23 +1703,28 @@ func (r *ChannelRouter) sendPaymentAttempt(paySession *paymentSession,
// this HTLC.
paymentID, err := r.cfg.NextPaymentID()
if err != nil {
return [32]byte{}, true, err
return [32]byte{}, nil, err
}
err = r.cfg.Payer.SendHTLC(
firstHop, paymentID, htlcAdd,
)
if err != nil {
log.Errorf("Failed sending attempt %d for payment %x to "+
"switch: %v", paymentID, paymentHash, err)
log.Errorf("Failed sending attempt %d for payment "+
"%x to switch: %v", paymentID, paymentHash, err)
// We must inspect the error to know whether it was critical or
// not, to decide whether we should continue trying.
// We must inspect the error to know whether it was
// critical or not, to decide whether we should
// continue trying.
finalOutcome := r.processSendError(
paySession, route, err,
)
if finalOutcome {
return [32]byte{}, nil, err
}
return [32]byte{}, finalOutcome, err
lastError = err
continue
}
// Using the created circuit, initialize the error decrypter so we can
@ -1753,7 +1742,7 @@ func (r *ChannelRouter) sendPaymentAttempt(paySession *paymentSession,
if err != nil {
log.Errorf("Failed getting result for paymentID %d "+
"from switch: %v", paymentID, err)
return [32]byte{}, true, err
return [32]byte{}, nil, err
}
var (
@ -1763,11 +1752,11 @@ func (r *ChannelRouter) sendPaymentAttempt(paySession *paymentSession,
select {
case result, ok = <-resultChan:
if !ok {
return [32]byte{}, true, htlcswitch.ErrSwitchExiting
return [32]byte{}, nil, htlcswitch.ErrSwitchExiting
}
case <-r.quit:
return [32]byte{}, true, ErrRouterShuttingDown
return [32]byte{}, nil, ErrRouterShuttingDown
}
if result.Error != nil {
@ -1778,10 +1767,17 @@ func (r *ChannelRouter) sendPaymentAttempt(paySession *paymentSession,
paySession, route, result.Error,
)
return [32]byte{}, finalOutcome, result.Error
if finalOutcome {
return [32]byte{}, nil, result.Error
}
lastError = result.Error
continue
}
return result.Preimage, route, nil
}
return result.Preimage, true, nil
}
// processSendError analyzes the error for the payment attempt received from the