routing: unify shardResult and launchOutcome to be attemptResult
This commit removes the `launchOutcome` and `shardResult` and uses `attemptResult` instead. This struct is also used in `failAttempt` so we can future distinguish critical vs non-critical errors when handling HTLC attempts.
This commit is contained in:
1 file changed
+28
-44
@@ -364,12 +364,12 @@ func (p *paymentLifecycle) checkShards() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// launchOutcome is a type returned from launchShard that indicates whether the
|
// attemptResult holds the HTLC attempt and a possible error returned from
|
||||||
// shard was successfully send onto the network.
|
// sending it.
|
||||||
type launchOutcome struct {
|
type attemptResult struct {
|
||||||
// err is non-nil if a non-critical error was encountered when trying
|
// err is non-nil if a non-critical error was encountered when trying
|
||||||
// to send the shard, and we successfully updated the control tower to
|
// to send the attempt, and we successfully updated the control tower
|
||||||
// reflect this error. This can be errors like not enough local
|
// to reflect this error. This can be errors like not enough local
|
||||||
// balance for the given route etc.
|
// balance for the given route etc.
|
||||||
err error
|
err error
|
||||||
|
|
||||||
@@ -386,7 +386,7 @@ type launchOutcome struct {
|
|||||||
// non-nil error, it means that the attempt was not sent onto the network, so
|
// non-nil error, it means that the attempt was not sent onto the network, so
|
||||||
// no result will be available in the future for it.
|
// no result will be available in the future for it.
|
||||||
func (p *paymentLifecycle) launchShard(rt *route.Route,
|
func (p *paymentLifecycle) launchShard(rt *route.Route,
|
||||||
lastShard bool) (*channeldb.HTLCAttempt, *launchOutcome, error) {
|
lastShard bool) (*channeldb.HTLCAttempt, *attemptResult, error) {
|
||||||
|
|
||||||
// Using the route received from the payment session, create a new
|
// Using the route received from the payment session, create a new
|
||||||
// shard to send.
|
// shard to send.
|
||||||
@@ -419,22 +419,13 @@ func (p *paymentLifecycle) launchShard(rt *route.Route,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Return a launchOutcome indicating the shard failed.
|
// Return a launchOutcome indicating the shard failed.
|
||||||
return attempt, &launchOutcome{
|
return attempt, &attemptResult{
|
||||||
attempt: htlcAttempt,
|
attempt: htlcAttempt.attempt,
|
||||||
err: sendErr,
|
err: sendErr,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return attempt, &launchOutcome{}, nil
|
return attempt, &attemptResult{}, nil
|
||||||
}
|
|
||||||
|
|
||||||
// shardResult holds the resulting outcome of a shard sent.
|
|
||||||
type shardResult struct {
|
|
||||||
// attempt is the attempt structure as recorded in the database.
|
|
||||||
attempt *channeldb.HTLCAttempt
|
|
||||||
|
|
||||||
// err indicates that the shard failed.
|
|
||||||
err error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// collectResultAsync launches a goroutine that will wait for the result of the
|
// collectResultAsync launches a goroutine that will wait for the result of the
|
||||||
@@ -493,10 +484,11 @@ func (p *paymentLifecycle) collectResultAsync(attempt *channeldb.HTLCAttempt) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// collectResult waits for the result for the given attempt to be available
|
// collectResult waits for the result for the given attempt to be available
|
||||||
// from the Switch, then records the attempt outcome with the control tower. A
|
// from the Switch, then records the attempt outcome with the control tower.
|
||||||
// shardResult is returned, indicating the final outcome of this HTLC attempt.
|
// An attemptResult is returned, indicating the final outcome of this HTLC
|
||||||
|
// attempt.
|
||||||
func (p *paymentLifecycle) collectResult(attempt *channeldb.HTLCAttempt) (
|
func (p *paymentLifecycle) collectResult(attempt *channeldb.HTLCAttempt) (
|
||||||
*shardResult, error) {
|
*attemptResult, error) {
|
||||||
|
|
||||||
// We'll retrieve the hash specific to this shard from the
|
// We'll retrieve the hash specific to this shard from the
|
||||||
// shardTracker, since it will be needed to regenerate the circuit
|
// shardTracker, since it will be needed to regenerate the circuit
|
||||||
@@ -536,15 +528,7 @@ func (p *paymentLifecycle) collectResult(attempt *channeldb.HTLCAttempt) (
|
|||||||
"the Switch, retrying.", attempt.AttemptID,
|
"the Switch, retrying.", attempt.AttemptID,
|
||||||
p.identifier)
|
p.identifier)
|
||||||
|
|
||||||
attempt, cErr := p.failAttempt(attempt.AttemptID, err)
|
return p.failAttempt(attempt.AttemptID, err)
|
||||||
if cErr != nil {
|
|
||||||
return nil, cErr
|
|
||||||
}
|
|
||||||
|
|
||||||
return &shardResult{
|
|
||||||
attempt: attempt,
|
|
||||||
err: err,
|
|
||||||
}, nil
|
|
||||||
|
|
||||||
// A critical, unexpected error was encountered.
|
// A critical, unexpected error was encountered.
|
||||||
case err != nil:
|
case err != nil:
|
||||||
@@ -574,15 +558,7 @@ func (p *paymentLifecycle) collectResult(attempt *channeldb.HTLCAttempt) (
|
|||||||
// In case of a payment failure, fail the attempt with the control
|
// In case of a payment failure, fail the attempt with the control
|
||||||
// tower and return.
|
// tower and return.
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
attempt, err := p.failAttempt(attempt.AttemptID, result.Error)
|
return p.failAttempt(attempt.AttemptID, result.Error)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return &shardResult{
|
|
||||||
attempt: attempt,
|
|
||||||
err: result.Error,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// We successfully got a payment result back from the switch.
|
// We successfully got a payment result back from the switch.
|
||||||
@@ -611,7 +587,7 @@ func (p *paymentLifecycle) collectResult(attempt *channeldb.HTLCAttempt) (
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &shardResult{
|
return &attemptResult{
|
||||||
attempt: htlcAttempt,
|
attempt: htlcAttempt,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
@@ -725,7 +701,7 @@ func (p *paymentLifecycle) sendAttempt(
|
|||||||
// router's control tower, which marks the payment as failed in db.
|
// router's control tower, which marks the payment as failed in db.
|
||||||
func (p *paymentLifecycle) failPaymentAndAttempt(
|
func (p *paymentLifecycle) failPaymentAndAttempt(
|
||||||
attemptID uint64, reason *channeldb.FailureReason,
|
attemptID uint64, reason *channeldb.FailureReason,
|
||||||
sendErr error) (*channeldb.HTLCAttempt, error) {
|
sendErr error) (*attemptResult, error) {
|
||||||
|
|
||||||
log.Errorf("Payment %v failed: final_outcome=%v, raw_err=%v",
|
log.Errorf("Payment %v failed: final_outcome=%v, raw_err=%v",
|
||||||
p.identifier, *reason, sendErr)
|
p.identifier, *reason, sendErr)
|
||||||
@@ -764,7 +740,7 @@ func (p *paymentLifecycle) handleSwitchErr(attempt *channeldb.HTLCAttempt,
|
|||||||
// the payment or not. If a non nil reason is returned from mission
|
// the payment or not. If a non nil reason is returned from mission
|
||||||
// control, it will further fail the payment via control tower.
|
// control, it will further fail the payment via control tower.
|
||||||
reportAndFail := func(srcIdx *int,
|
reportAndFail := func(srcIdx *int,
|
||||||
msg lnwire.FailureMessage) (*channeldb.HTLCAttempt, error) {
|
msg lnwire.FailureMessage) (*attemptResult, error) {
|
||||||
|
|
||||||
// Report outcome to mission control.
|
// Report outcome to mission control.
|
||||||
reason, err := p.router.cfg.MissionControl.ReportPaymentFail(
|
reason, err := p.router.cfg.MissionControl.ReportPaymentFail(
|
||||||
@@ -915,7 +891,7 @@ func (p *paymentLifecycle) handleFailureMessage(rt *route.Route,
|
|||||||
|
|
||||||
// failAttempt calls control tower to fail the current payment attempt.
|
// failAttempt calls control tower to fail the current payment attempt.
|
||||||
func (p *paymentLifecycle) failAttempt(attemptID uint64,
|
func (p *paymentLifecycle) failAttempt(attemptID uint64,
|
||||||
sendError error) (*channeldb.HTLCAttempt, error) {
|
sendError error) (*attemptResult, error) {
|
||||||
|
|
||||||
log.Warnf("Attempt %v for payment %v failed: %v", attemptID,
|
log.Warnf("Attempt %v for payment %v failed: %v", attemptID,
|
||||||
p.identifier, sendError)
|
p.identifier, sendError)
|
||||||
@@ -932,9 +908,17 @@ func (p *paymentLifecycle) failAttempt(attemptID uint64,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.router.cfg.Control.FailAttempt(
|
attempt, err := p.router.cfg.Control.FailAttempt(
|
||||||
p.identifier, attemptID, failInfo,
|
p.identifier, attemptID, failInfo,
|
||||||
)
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &attemptResult{
|
||||||
|
attempt: attempt,
|
||||||
|
err: sendError,
|
||||||
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// marshallError marshall an error as received from the switch to a structure
|
// marshallError marshall an error as received from the switch to a structure
|
||||||
|
|||||||
Reference in new issue
Block a user