htlcswitch+invoices: fail mpp timeouts with FailMPPTimeout
This commit adds a getResolutionFailure function which returns an appropriate wire failure based on the outcome of a htlc resolution. It also updates the MissionControlStore test to ensure that lnd can handle failures which occur due to mpp timeout.
This commit is contained in:
parent
1d3bb5aed6
commit
e0c86f1e71
@ -1209,12 +1209,8 @@ func (l *channelLink) processHtlcResolution(resolution invoices.HtlcResolution,
|
|||||||
l.log.Debugf("received cancel resolution for %v with outcome: %v",
|
l.log.Debugf("received cancel resolution for %v with outcome: %v",
|
||||||
circuitKey, resolution.Outcome)
|
circuitKey, resolution.Outcome)
|
||||||
|
|
||||||
// The htlc has failed so we cancel it with FailIncorrectDetails. This
|
// Get the lnwire failure message based on the resolution result.
|
||||||
// error covers invoice failures and hodl cancels (which return it to avoid
|
failure := getResolutionFailure(resolution, htlc.pd.Amount)
|
||||||
// leaking information).
|
|
||||||
failure := lnwire.NewFailIncorrectDetails(
|
|
||||||
htlc.pd.Amount, uint32(resolution.AcceptHeight),
|
|
||||||
)
|
|
||||||
|
|
||||||
l.sendHTLCError(
|
l.sendHTLCError(
|
||||||
htlc.pd.HtlcIndex, failure, htlc.obfuscator,
|
htlc.pd.HtlcIndex, failure, htlc.obfuscator,
|
||||||
@ -1223,6 +1219,25 @@ func (l *channelLink) processHtlcResolution(resolution invoices.HtlcResolution,
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getResolutionFailure returns the wire message that a htlc resolution should
|
||||||
|
// be failed with.
|
||||||
|
func getResolutionFailure(resolution invoices.HtlcResolution,
|
||||||
|
amount lnwire.MilliSatoshi) lnwire.FailureMessage {
|
||||||
|
|
||||||
|
// If the resolution has been resolved as part of a MPP timeout, we need
|
||||||
|
// to fail the htlc with lnwire.FailMppTimeout.
|
||||||
|
if resolution.Outcome == invoices.ResultMppTimeout {
|
||||||
|
return &lnwire.FailMPPTimeout{}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the htlc is not a MPP timeout, we fail it with FailIncorrectDetails
|
||||||
|
// This covers hodl cancels (which return it to avoid leaking information
|
||||||
|
// and other invoice failures such as underpayment or expiry too soon.
|
||||||
|
return lnwire.NewFailIncorrectDetails(
|
||||||
|
amount, uint32(resolution.AcceptHeight),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// randomFeeUpdateTimeout returns a random timeout between the bounds defined
|
// randomFeeUpdateTimeout returns a random timeout between the bounds defined
|
||||||
// within the link's configuration that will be used to determine when the link
|
// within the link's configuration that will be used to determine when the link
|
||||||
// should propose an update to its commitment fee rate.
|
// should propose an update to its commitment fee rate.
|
||||||
|
@ -16,8 +16,12 @@ import (
|
|||||||
|
|
||||||
const testMaxRecords = 2
|
const testMaxRecords = 2
|
||||||
|
|
||||||
|
// TestMissionControlStore tests the recording of payment failure events
|
||||||
|
// in mission control. It tests encoding and decoding of differing lnwire
|
||||||
|
// failures (FailIncorrectDetails and FailMppTimeout), pruning of results
|
||||||
|
// and idempotent writes.
|
||||||
func TestMissionControlStore(t *testing.T) {
|
func TestMissionControlStore(t *testing.T) {
|
||||||
// Set time zone explictly to keep test deterministic.
|
// Set time zone explicitly to keep test deterministic.
|
||||||
time.Local = time.UTC
|
time.Local = time.UTC
|
||||||
|
|
||||||
file, err := ioutil.TempFile("", "*.db")
|
file, err := ioutil.TempFile("", "*.db")
|
||||||
@ -115,11 +119,12 @@ func TestMissionControlStore(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a newer result.
|
// Add a newer result which failed due to mpp timeout.
|
||||||
result3 := result1
|
result3 := result1
|
||||||
result3.timeReply = result1.timeReply.Add(2 * time.Hour)
|
result3.timeReply = result1.timeReply.Add(2 * time.Hour)
|
||||||
result3.timeFwd = result1.timeReply.Add(2 * time.Hour)
|
result3.timeFwd = result1.timeReply.Add(2 * time.Hour)
|
||||||
result3.id = 3
|
result3.id = 3
|
||||||
|
result3.failure = &lnwire.FailMPPTimeout{}
|
||||||
|
|
||||||
err = store.AddResult(&result3)
|
err = store.AddResult(&result3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
Loading…
Reference in New Issue
Block a user