mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-10-09 18:13:59 +02:00
channeldb: expand PaymentStatus to explicitly represent payment status
This commit introduces more granular statuses to better determine a payment's current state. Based on whether there are inflight HTLCs, the state of each of the HTLCs, and whether the payment is failed, a total of 5 states are derived, which can give a finer control over what action to take based on a given state. Also, `fetchPayment` now uses `decidePaymentStatus`. After applying the new function, the returned payment status would be different, ``` | inflight | settled | failed | reason | previous -> now | |:--------:|:-------:|:------:|:------:|:---------------------------------:| | true | true | true | yes | StatusInFlight(unchanged) | | true | true | true | no | StatusInFlight(unchanged) | | true | true | false | yes | StatusInFlight(unchanged) | | true | true | false | no | StatusInFlight(unchanged) | | true | false | true | yes | StatusInFlight(unchanged) | | true | false | true | no | StatusInFlight(unchanged) | | true | false | false | yes | StatusInFlight(unchanged) | | true | false | false | no | StatusInFlight(unchanged) | | false | true | true | yes | StatusSucceeded(unchanged) | | false | true | true | no | StatusSucceeded(unchanged) | | false | true | false | yes | StatusSucceeded(unchanged) | | false | true | false | no | StatusSucceeded(unchanged) | | false | false | true | yes | StatusFailed(unchanged) | | false | false | true | no | StatusInFlight(unchanged) | | false | false | false | yes | StatusFailed(unchanged) | | false | false | false | no | StatusInFlight -> StatusInitiated| ```
This commit is contained in:
committed by
Olaoluwa Osuntokun
parent
09b67af48d
commit
390f3c8253
@@ -4,6 +4,7 @@ import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
@@ -67,7 +68,9 @@ func TestPaymentControlSwitchFail(t *testing.T) {
|
||||
require.NoError(t, err, "unable to send htlc message")
|
||||
|
||||
assertPaymentIndex(t, pControl, info.PaymentIdentifier)
|
||||
assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
|
||||
assertPaymentStatus(
|
||||
t, pControl, info.PaymentIdentifier, StatusInitiated,
|
||||
)
|
||||
assertPaymentInfo(
|
||||
t, pControl, info.PaymentIdentifier, info, nil, nil,
|
||||
)
|
||||
@@ -98,7 +101,9 @@ func TestPaymentControlSwitchFail(t *testing.T) {
|
||||
assertPaymentIndex(t, pControl, info.PaymentIdentifier)
|
||||
assertNoIndex(t, pControl, payment.SequenceNum)
|
||||
|
||||
assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
|
||||
assertPaymentStatus(
|
||||
t, pControl, info.PaymentIdentifier, StatusInitiated,
|
||||
)
|
||||
assertPaymentInfo(
|
||||
t, pControl, info.PaymentIdentifier, info, nil, nil,
|
||||
)
|
||||
@@ -119,7 +124,9 @@ func TestPaymentControlSwitchFail(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
|
||||
assertPaymentStatus(
|
||||
t, pControl, info.PaymentIdentifier, StatusInFlight,
|
||||
)
|
||||
|
||||
htlc := &htlcStatus{
|
||||
HTLCAttemptInfo: attempt,
|
||||
@@ -198,7 +205,9 @@ func TestPaymentControlSwitchDoubleSend(t *testing.T) {
|
||||
require.NoError(t, err, "unable to send htlc message")
|
||||
|
||||
assertPaymentIndex(t, pControl, info.PaymentIdentifier)
|
||||
assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
|
||||
assertPaymentStatus(
|
||||
t, pControl, info.PaymentIdentifier, StatusInitiated,
|
||||
)
|
||||
assertPaymentInfo(
|
||||
t, pControl, info.PaymentIdentifier, info, nil, nil,
|
||||
)
|
||||
@@ -207,10 +216,9 @@ func TestPaymentControlSwitchDoubleSend(t *testing.T) {
|
||||
// payment hash, should result in error indicating that payment has
|
||||
// already been sent.
|
||||
err = pControl.InitPayment(info.PaymentIdentifier, info)
|
||||
if err != ErrPaymentInFlight {
|
||||
t.Fatalf("payment control wrong behaviour: " +
|
||||
"double sending must trigger ErrPaymentInFlight error")
|
||||
}
|
||||
require.Equal(t, ErrPaymentExists, err, "payment control wrong "+
|
||||
"behaviour: init payment again must trigger ErrPaymentExists "+
|
||||
"error")
|
||||
|
||||
// Record an attempt.
|
||||
_, err = pControl.RegisterAttempt(info.PaymentIdentifier, attempt)
|
||||
@@ -682,7 +690,9 @@ func TestPaymentControlMultiShard(t *testing.T) {
|
||||
}
|
||||
|
||||
assertPaymentIndex(t, pControl, info.PaymentIdentifier)
|
||||
assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
|
||||
assertPaymentStatus(
|
||||
t, pControl, info.PaymentIdentifier, StatusInitiated,
|
||||
)
|
||||
assertPaymentInfo(
|
||||
t, pControl, info.PaymentIdentifier, info, nil, nil,
|
||||
)
|
||||
@@ -708,7 +718,8 @@ func TestPaymentControlMultiShard(t *testing.T) {
|
||||
t.Fatalf("unable to send htlc message: %v", err)
|
||||
}
|
||||
assertPaymentStatus(
|
||||
t, pControl, info.PaymentIdentifier, StatusInFlight,
|
||||
t, pControl, info.PaymentIdentifier,
|
||||
StatusInFlight,
|
||||
)
|
||||
|
||||
htlc := &htlcStatus{
|
||||
@@ -807,11 +818,14 @@ func TestPaymentControlMultiShard(t *testing.T) {
|
||||
// Record the reason we failed the payment, such that
|
||||
// we can assert this later in the test.
|
||||
firstFailReason = &failReason
|
||||
}
|
||||
|
||||
// The payment should still be considered in-flight, since there
|
||||
// is still an active HTLC.
|
||||
assertPaymentStatus(t, pControl, info.PaymentIdentifier, StatusInFlight)
|
||||
// The payment is now considered pending fail, since
|
||||
// there is still an active HTLC.
|
||||
assertPaymentStatus(
|
||||
t, pControl, info.PaymentIdentifier,
|
||||
StatusInFlight,
|
||||
)
|
||||
}
|
||||
|
||||
// Try to register yet another attempt. This should fail now
|
||||
// that the payment has reached a terminal condition.
|
||||
@@ -839,15 +853,12 @@ func TestPaymentControlMultiShard(t *testing.T) {
|
||||
Preimage: preimg,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatalf("error shouldn't have been "+
|
||||
"received, got: %v", err)
|
||||
}
|
||||
require.NoError(t, err, "unable to settle")
|
||||
|
||||
htlc.settle = &preimg
|
||||
assertPaymentInfo(
|
||||
t, pControl, info.PaymentIdentifier, info,
|
||||
firstFailReason, htlc,
|
||||
t, pControl, info.PaymentIdentifier,
|
||||
info, firstFailReason, htlc,
|
||||
)
|
||||
} else {
|
||||
// Fail the attempt.
|
||||
@@ -875,9 +886,7 @@ func TestPaymentControlMultiShard(t *testing.T) {
|
||||
// syncing.
|
||||
failReason := FailureReasonPaymentDetails
|
||||
_, err = pControl.Fail(info.PaymentIdentifier, failReason)
|
||||
if err != nil {
|
||||
t.Fatalf("unable to fail payment hash: %v", err)
|
||||
}
|
||||
require.NoError(t, err, "unable to fail")
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -1105,7 +1114,7 @@ func assertPaymentStatus(t *testing.T, p *PaymentControl,
|
||||
t.Helper()
|
||||
|
||||
payment, err := p.FetchPayment(hash)
|
||||
if err == ErrPaymentNotInitiated {
|
||||
if errors.Is(err, ErrPaymentNotInitiated) {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user