routing/payment_lifecycle: move attempt DB checkpointing into payment

loop

To prepare for multiple in flight payment attempts, we move
checkpointing the payment attempt out of createNewPaymentAttempt and
into the main payment lifecycle loop.

We'll attempt to move all calls to the DB via the ControlTower into this
loop, so we can more easily handle them in sequence.
This commit is contained in:
Johan T. Halseth 2020-04-01 00:13:23 +02:00
parent e61fcda6a9
commit 3620721391
No known key found for this signature in database
GPG Key ID: 15BAADA29DA20D26

@ -114,12 +114,24 @@ func (p *paymentLifecycle) resumePayment() ([32]byte, *route.Route, error) {
// Using the route received from the payment session,
// create a new shard to send.
firstHop, htlcAdd, err := p.createNewPaymentAttempt(
firstHop, htlcAdd, attempt, err := p.createNewPaymentAttempt(
rt,
)
if err != nil {
return [32]byte{}, nil, err
}
p.attempt = attempt
// Before sending this HTLC to the switch, we checkpoint the
// fresh paymentID and route to the DB. This lets us know on
// startup the ID of the payment that we attempted to send,
// such that we can query the Switch for its whereabouts. The
// route is needed to handle the result when it eventually
// comes back.
err = p.router.cfg.Control.RegisterAttempt(p.paymentHash, attempt)
if err != nil {
return [32]byte{}, nil, err
}
// Now that the attempt is created and checkpointed to
// the DB, we send it.
@ -297,15 +309,15 @@ func errorToPaymentFailure(err error) channeldb.FailureReason {
return channeldb.FailureReasonError
}
// createNewPaymentAttempt creates and stores a new payment attempt to the
// database.
func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route) (lnwire.ShortChannelID,
*lnwire.UpdateAddHTLC, error) {
// createNewPaymentAttempt creates a new payment attempt from the given route.
func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route) (
lnwire.ShortChannelID, *lnwire.UpdateAddHTLC,
*channeldb.HTLCAttemptInfo, error) {
// Generate a new key to be used for this attempt.
sessionKey, err := generateNewSessionKey()
if err != nil {
return lnwire.ShortChannelID{}, nil, err
return lnwire.ShortChannelID{}, nil, nil, err
}
// Generate the raw encoded sphinx packet to be included along
@ -327,13 +339,13 @@ func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route) (lnwire.Shor
p.paymentHash, channeldb.FailureReasonError,
)
if controlErr != nil {
return lnwire.ShortChannelID{}, nil, controlErr
return lnwire.ShortChannelID{}, nil, nil, controlErr
}
}
// In any case, don't continue if there is an error.
if err != nil {
return lnwire.ShortChannelID{}, nil, err
return lnwire.ShortChannelID{}, nil, nil, err
}
// Update our cached circuit with the newly generated
@ -361,30 +373,19 @@ func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route) (lnwire.Shor
// this HTLC.
attemptID, err := p.router.cfg.NextPaymentID()
if err != nil {
return lnwire.ShortChannelID{}, nil, err
return lnwire.ShortChannelID{}, nil, nil, err
}
// We now have all the information needed to populate
// the current attempt information.
p.attempt = &channeldb.HTLCAttemptInfo{
attempt := &channeldb.HTLCAttemptInfo{
AttemptID: attemptID,
AttemptTime: p.router.cfg.Clock.Now(),
SessionKey: sessionKey,
Route: *rt,
}
// Before sending this HTLC to the switch, we checkpoint the
// fresh attemptID and route to the DB. This lets us know on
// startup the ID of the payment that we attempted to send,
// such that we can query the Switch for its whereabouts. The
// route is needed to handle the result when it eventually
// comes back.
err = p.router.cfg.Control.RegisterAttempt(p.paymentHash, p.attempt)
if err != nil {
return lnwire.ShortChannelID{}, nil, err
}
return firstHop, htlcAdd, nil
return firstHop, htlcAdd, attempt, nil
}
// sendPaymentAttempt attempts to send the current attempt to the switch.