diff --git a/channeldb/duplicate_payments.go b/channeldb/duplicate_payments.go index cae3e956a..004722f00 100644 --- a/channeldb/duplicate_payments.go +++ b/channeldb/duplicate_payments.go @@ -11,6 +11,7 @@ import ( "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/routing/route" ) @@ -74,7 +75,7 @@ func fetchDuplicatePaymentStatus(bucket kvdb.RBucket) (PaymentStatus, error) { return StatusInFlight, nil } - return 0, ErrPaymentNotInitiated + return 0, paymentsdb.ErrPaymentNotInitiated } func deserializeDuplicateHTLCAttemptInfo(r io.Reader) ( diff --git a/channeldb/mp_payment.go b/channeldb/mp_payment.go index b94bfd418..f75357afc 100644 --- a/channeldb/mp_payment.go +++ b/channeldb/mp_payment.go @@ -15,6 +15,7 @@ import ( "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnutils" "github.com/lightningnetwork/lnd/lnwire" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/routing/route" ) @@ -349,12 +350,12 @@ func (m *MPPayment) Registrable() error { // are settled HTLCs or the payment is failed. If we already have // settled HTLCs, we won't allow adding more HTLCs. if m.State.HasSettledHTLC { - return ErrPaymentPendingSettled + return paymentsdb.ErrPaymentPendingSettled } // If the payment is already failed, we won't allow adding more HTLCs. if m.State.PaymentFailed { - return ErrPaymentPendingFailed + return paymentsdb.ErrPaymentPendingFailed } // Otherwise we can add more HTLCs. @@ -371,8 +372,8 @@ func (m *MPPayment) setState() error { // Sanity check we haven't sent a value larger than the payment amount. totalAmt := m.Info.Value if sentAmt > totalAmt { - return fmt.Errorf("%w: sent=%v, total=%v", ErrSentExceedsTotal, - sentAmt, totalAmt) + return fmt.Errorf("%w: sent=%v, total=%v", + paymentsdb.ErrSentExceedsTotal, sentAmt, totalAmt) } // Get any terminal info for this payment. @@ -451,7 +452,7 @@ func (m *MPPayment) NeedWaitAttempts() (bool, error) { case StatusSucceeded: return false, fmt.Errorf("%w: parts of the payment "+ "already succeeded but still have remaining "+ - "amount %v", ErrPaymentInternal, + "amount %v", paymentsdb.ErrPaymentInternal, m.State.RemainingAmt) // The payment is failed and we have no inflight HTLCs, no need @@ -462,7 +463,7 @@ func (m *MPPayment) NeedWaitAttempts() (bool, error) { // Unknown payment status. default: return false, fmt.Errorf("%w: %s", - ErrUnknownPaymentStatus, m.Status) + paymentsdb.ErrUnknownPaymentStatus, m.Status) } } @@ -472,7 +473,8 @@ func (m *MPPayment) NeedWaitAttempts() (bool, error) { // When the payment is newly created, yet the payment has no remaining // amount, return an error. case StatusInitiated: - return false, fmt.Errorf("%w: %v", ErrPaymentInternal, m.Status) + return false, fmt.Errorf("%w: %v", + paymentsdb.ErrPaymentInternal, m.Status) // If the payment is inflight, we must wait. // @@ -493,12 +495,13 @@ func (m *MPPayment) NeedWaitAttempts() (bool, error) { // marked as failed with a reason, which means the remainingAmt must // not be zero because our sentAmt is zero. case StatusFailed: - return false, fmt.Errorf("%w: %v", ErrPaymentInternal, m.Status) + return false, fmt.Errorf("%w: %v", + paymentsdb.ErrPaymentInternal, m.Status) // Unknown payment status. default: - return false, fmt.Errorf("%w: %s", ErrUnknownPaymentStatus, - m.Status) + return false, fmt.Errorf("%w: %s", + paymentsdb.ErrUnknownPaymentStatus, m.Status) } } @@ -528,7 +531,8 @@ func (m *MPPayment) AllowMoreAttempts() (bool, error) { // remainingAmt, return an error. if m.Status == StatusInitiated { return false, fmt.Errorf("%w: initiated payment has "+ - "zero remainingAmt", ErrPaymentInternal) + "zero remainingAmt", + paymentsdb.ErrPaymentInternal) } // Otherwise, exit early since all other statuses with zero @@ -544,8 +548,8 @@ func (m *MPPayment) AllowMoreAttempts() (bool, error) { // as the preimage is received. In this case, return an error state. if m.Status == StatusSucceeded { return false, fmt.Errorf("%w: payment already succeeded but "+ - "still have remaining amount %v", ErrPaymentInternal, - m.State.RemainingAmt) + "still have remaining amount %v", + paymentsdb.ErrPaymentInternal, m.State.RemainingAmt) } // Now check if we can register a new HTLC. diff --git a/channeldb/mp_payment_test.go b/channeldb/mp_payment_test.go index 13e39871a..455a04de0 100644 --- a/channeldb/mp_payment_test.go +++ b/channeldb/mp_payment_test.go @@ -8,6 +8,7 @@ import ( "github.com/btcsuite/btcd/btcec/v2" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" ) @@ -65,35 +66,35 @@ func TestRegistrable(t *testing.T) { // Test inflight status with settled HTLC but no failed // payment. status: StatusInFlight, - registryErr: ErrPaymentPendingSettled, + registryErr: paymentsdb.ErrPaymentPendingSettled, hasSettledHTLC: true, }, { // Test inflight status with no settled HTLC but failed // payment. status: StatusInFlight, - registryErr: ErrPaymentPendingFailed, + registryErr: paymentsdb.ErrPaymentPendingFailed, paymentFailed: true, }, { // Test error state with settled HTLC and failed // payment. status: 0, - registryErr: ErrUnknownPaymentStatus, + registryErr: paymentsdb.ErrUnknownPaymentStatus, hasSettledHTLC: true, paymentFailed: true, }, { status: StatusSucceeded, - registryErr: ErrPaymentAlreadySucceeded, + registryErr: paymentsdb.ErrPaymentAlreadySucceeded, }, { status: StatusFailed, - registryErr: ErrPaymentAlreadyFailed, + registryErr: paymentsdb.ErrPaymentAlreadyFailed, }, { status: 0, - registryErr: ErrUnknownPaymentStatus, + registryErr: paymentsdb.ErrUnknownPaymentStatus, }, } @@ -149,7 +150,7 @@ func TestPaymentSetState(t *testing.T) { }, }, totalAmt: 1, - errExpected: ErrSentExceedsTotal, + errExpected: paymentsdb.ErrSentExceedsTotal, }, { // Test that when the htlc is failed, the fee is not @@ -294,7 +295,7 @@ func TestNeedWaitAttempts(t *testing.T) { status: StatusSucceeded, remainingAmt: 1000, needWait: false, - expectedErr: ErrPaymentInternal, + expectedErr: paymentsdb.ErrPaymentInternal, }, { // Payment is in terminal state, no need to wait. @@ -309,7 +310,7 @@ func TestNeedWaitAttempts(t *testing.T) { status: StatusInitiated, remainingAmt: 0, needWait: false, - expectedErr: ErrPaymentInternal, + expectedErr: paymentsdb.ErrPaymentInternal, }, { // With zero remainingAmt we must wait for the results. @@ -330,21 +331,21 @@ func TestNeedWaitAttempts(t *testing.T) { status: StatusFailed, remainingAmt: 0, needWait: false, - expectedErr: ErrPaymentInternal, + expectedErr: paymentsdb.ErrPaymentInternal, }, { // Payment is in an unknown status, return an error. status: 0, remainingAmt: 0, needWait: false, - expectedErr: ErrUnknownPaymentStatus, + expectedErr: paymentsdb.ErrUnknownPaymentStatus, }, { // Payment is in an unknown status, return an error. status: 0, remainingAmt: 1000, needWait: false, - expectedErr: ErrUnknownPaymentStatus, + expectedErr: paymentsdb.ErrUnknownPaymentStatus, }, } @@ -397,7 +398,7 @@ func TestAllowMoreAttempts(t *testing.T) { status: StatusInitiated, remainingAmt: 0, allowMore: false, - expectedErr: ErrPaymentInternal, + expectedErr: paymentsdb.ErrPaymentInternal, }, { // With zero remainingAmt we don't allow more HTLC @@ -505,7 +506,7 @@ func TestAllowMoreAttempts(t *testing.T) { remainingAmt: 1000, hasSettledHTLC: true, allowMore: false, - expectedErr: ErrPaymentInternal, + expectedErr: paymentsdb.ErrPaymentInternal, }, { // With the payment failed with no inflight HTLCs, we diff --git a/channeldb/payment_status.go b/channeldb/payment_status.go index 45018449a..179e22fc2 100644 --- a/channeldb/payment_status.go +++ b/channeldb/payment_status.go @@ -1,6 +1,10 @@ package channeldb -import "fmt" +import ( + "fmt" + + paymentsdb "github.com/lightningnetwork/lnd/payments/db" +) // PaymentStatus represent current status of payment. type PaymentStatus byte @@ -58,24 +62,25 @@ func (ps PaymentStatus) initializable() error { // again in case other goroutines have already been creating HTLCs for // it. case StatusInitiated: - return ErrPaymentExists + return paymentsdb.ErrPaymentExists // We already have an InFlight payment on the network. We will disallow // any new payments. case StatusInFlight: - return ErrPaymentInFlight + return paymentsdb.ErrPaymentInFlight // The payment has been attempted and is succeeded so we won't allow // creating it again. case StatusSucceeded: - return ErrAlreadyPaid + return paymentsdb.ErrAlreadyPaid // We allow retrying failed payments. case StatusFailed: return nil default: - return fmt.Errorf("%w: %v", ErrUnknownPaymentStatus, ps) + return fmt.Errorf("%w: %v", paymentsdb.ErrUnknownPaymentStatus, + ps) } } @@ -91,7 +96,7 @@ func (ps PaymentStatus) removable() error { // There are still inflight HTLCs and the payment needs to wait for the // final outcomes. case StatusInFlight: - return ErrPaymentInFlight + return paymentsdb.ErrPaymentInFlight // The payment has been attempted and is succeeded and is allowed to be // removed. @@ -103,7 +108,8 @@ func (ps PaymentStatus) removable() error { return nil default: - return fmt.Errorf("%w: %v", ErrUnknownPaymentStatus, ps) + return fmt.Errorf("%w: %v", paymentsdb.ErrUnknownPaymentStatus, + ps) } } @@ -121,13 +127,14 @@ func (ps PaymentStatus) updatable() error { // If the payment has a terminal condition, we won't allow any updates. case StatusSucceeded: - return ErrPaymentAlreadySucceeded + return paymentsdb.ErrPaymentAlreadySucceeded case StatusFailed: - return ErrPaymentAlreadyFailed + return paymentsdb.ErrPaymentAlreadyFailed default: - return fmt.Errorf("%w: %v", ErrUnknownPaymentStatus, ps) + return fmt.Errorf("%w: %v", paymentsdb.ErrUnknownPaymentStatus, + ps) } } diff --git a/channeldb/payment_status_test.go b/channeldb/payment_status_test.go index f82162319..bd6181870 100644 --- a/channeldb/payment_status_test.go +++ b/channeldb/payment_status_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/lightningnetwork/lnd/lntypes" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/stretchr/testify/require" ) @@ -197,33 +198,33 @@ func TestPaymentStatusActions(t *testing.T) { }{ { status: StatusInitiated, - initErr: ErrPaymentExists, + initErr: paymentsdb.ErrPaymentExists, updateErr: nil, removeErr: nil, }, { status: StatusInFlight, - initErr: ErrPaymentInFlight, + initErr: paymentsdb.ErrPaymentInFlight, updateErr: nil, - removeErr: ErrPaymentInFlight, + removeErr: paymentsdb.ErrPaymentInFlight, }, { status: StatusSucceeded, - initErr: ErrAlreadyPaid, - updateErr: ErrPaymentAlreadySucceeded, + initErr: paymentsdb.ErrAlreadyPaid, + updateErr: paymentsdb.ErrPaymentAlreadySucceeded, removeErr: nil, }, { status: StatusFailed, initErr: nil, - updateErr: ErrPaymentAlreadyFailed, + updateErr: paymentsdb.ErrPaymentAlreadyFailed, removeErr: nil, }, { status: 0, - initErr: ErrUnknownPaymentStatus, - updateErr: ErrUnknownPaymentStatus, - removeErr: ErrUnknownPaymentStatus, + initErr: paymentsdb.ErrUnknownPaymentStatus, + updateErr: paymentsdb.ErrUnknownPaymentStatus, + removeErr: paymentsdb.ErrUnknownPaymentStatus, }, } diff --git a/channeldb/payments_kv_store.go b/channeldb/payments_kv_store.go index ab98d42d1..4c1880a8b 100644 --- a/channeldb/payments_kv_store.go +++ b/channeldb/payments_kv_store.go @@ -16,6 +16,7 @@ import ( "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/tlv" @@ -31,113 +32,6 @@ const ( paymentProgressLogInterval = 30 * time.Second ) -var ( - // ErrAlreadyPaid signals we have already paid this payment hash. - ErrAlreadyPaid = errors.New("invoice is already paid") - - // ErrPaymentInFlight signals that payment for this payment hash is - // already "in flight" on the network. - ErrPaymentInFlight = errors.New("payment is in transition") - - // ErrPaymentExists is returned when we try to initialize an already - // existing payment that is not failed. - ErrPaymentExists = errors.New("payment already exists") - - // ErrPaymentInternal is returned when performing the payment has a - // conflicting state, such as, - // - payment has StatusSucceeded but remaining amount is not zero. - // - payment has StatusInitiated but remaining amount is zero. - // - payment has StatusFailed but remaining amount is zero. - ErrPaymentInternal = errors.New("internal error") - - // ErrPaymentNotInitiated is returned if the payment wasn't initiated. - ErrPaymentNotInitiated = errors.New("payment isn't initiated") - - // ErrPaymentAlreadySucceeded is returned in the event we attempt to - // change the status of a payment already succeeded. - ErrPaymentAlreadySucceeded = errors.New("payment is already succeeded") - - // ErrPaymentAlreadyFailed is returned in the event we attempt to alter - // a failed payment. - ErrPaymentAlreadyFailed = errors.New("payment has already failed") - - // ErrUnknownPaymentStatus is returned when we do not recognize the - // existing state of a payment. - ErrUnknownPaymentStatus = errors.New("unknown payment status") - - // ErrPaymentTerminal is returned if we attempt to alter a payment that - // already has reached a terminal condition. - ErrPaymentTerminal = errors.New("payment has reached terminal " + - "condition") - - // ErrAttemptAlreadySettled is returned if we try to alter an already - // settled HTLC attempt. - ErrAttemptAlreadySettled = errors.New("attempt already settled") - - // ErrAttemptAlreadyFailed is returned if we try to alter an already - // failed HTLC attempt. - ErrAttemptAlreadyFailed = errors.New("attempt already failed") - - // ErrValueMismatch is returned if we try to register a non-MPP attempt - // with an amount that doesn't match the payment amount. - ErrValueMismatch = errors.New("attempted value doesn't match payment " + - "amount") - - // ErrValueExceedsAmt is returned if we try to register an attempt that - // would take the total sent amount above the payment amount. - ErrValueExceedsAmt = errors.New("attempted value exceeds payment " + - "amount") - - // ErrNonMPPayment is returned if we try to register an MPP attempt for - // a payment that already has a non-MPP attempt registered. - ErrNonMPPayment = errors.New("payment has non-MPP attempts") - - // ErrMPPayment is returned if we try to register a non-MPP attempt for - // a payment that already has an MPP attempt registered. - ErrMPPayment = errors.New("payment has MPP attempts") - - // ErrMPPRecordInBlindedPayment is returned if we try to register an - // attempt with an MPP record for a payment to a blinded path. - ErrMPPRecordInBlindedPayment = errors.New("blinded payment cannot " + - "contain MPP records") - - // ErrBlindedPaymentTotalAmountMismatch is returned if we try to - // register an HTLC shard to a blinded route where the total amount - // doesn't match existing shards. - ErrBlindedPaymentTotalAmountMismatch = errors.New("blinded path " + - "total amount mismatch") - - // ErrMPPPaymentAddrMismatch is returned if we try to register an MPP - // shard where the payment address doesn't match existing shards. - ErrMPPPaymentAddrMismatch = errors.New("payment address mismatch") - - // ErrMPPTotalAmountMismatch is returned if we try to register an MPP - // shard where the total amount doesn't match existing shards. - ErrMPPTotalAmountMismatch = errors.New("mp payment total amount " + - "mismatch") - - // ErrPaymentPendingSettled is returned when we try to add a new - // attempt to a payment that has at least one of its HTLCs settled. - ErrPaymentPendingSettled = errors.New("payment has settled htlcs") - - // ErrPaymentPendingFailed is returned when we try to add a new attempt - // to a payment that already has a failure reason. - ErrPaymentPendingFailed = errors.New("payment has failure reason") - - // ErrSentExceedsTotal is returned if the payment's current total sent - // amount exceed the total amount. - ErrSentExceedsTotal = errors.New("total sent exceeds total amount") - - // errNoAttemptInfo is returned when no attempt info is stored yet. - errNoAttemptInfo = errors.New("unable to find attempt info for " + - "inflight payment") - - // errNoSequenceNrIndex is returned when an attempt to lookup a payment - // index is made for a sequence number that is not indexed. - errNoSequenceNrIndex = errors.New("payment sequence number index " + - "does not exist") -) - //nolint:ll var ( // paymentsRootBucket is the name of the top-level bucket within the @@ -223,26 +117,6 @@ var ( paymentsIndexBucket = []byte("payments-index-bucket") ) -var ( - // ErrNoSequenceNumber is returned if we look up a payment which does - // not have a sequence number. - ErrNoSequenceNumber = errors.New("sequence number not found") - - // ErrDuplicateNotFound is returned when we lookup a payment by its - // index and cannot find a payment with a matching sequence number. - ErrDuplicateNotFound = errors.New("duplicate payment not found") - - // ErrNoDuplicateBucket is returned when we expect to find duplicates - // when looking up a payment from its index, but the payment does not - // have any. - ErrNoDuplicateBucket = errors.New("expected duplicate bucket") - - // ErrNoDuplicateNestedBucket is returned if we do not find duplicate - // payments in their own sub-bucket. - ErrNoDuplicateNestedBucket = errors.New("nested duplicate bucket not " + - "found") -) - // KVPaymentsDB implements persistence for payments and payment attempts. type KVPaymentsDB struct { paymentSeqMx sync.Mutex @@ -306,7 +180,7 @@ func (p *KVPaymentsDB) InitPayment(paymentHash lntypes.Hash, // Otherwise, if the error is not `ErrPaymentNotInitiated`, // we'll return the error. - case !errors.Is(err, ErrPaymentNotInitiated): + case !errors.Is(err, paymentsdb.ErrPaymentNotInitiated): return err } @@ -480,7 +354,7 @@ func (p *KVPaymentsDB) RegisterAttempt(paymentHash lntypes.Hash, // MPP records should not be set for attempts to blinded paths. if isBlinded && mpp != nil { - return ErrMPPRecordInBlindedPayment + return paymentsdb.ErrMPPRecordInBlindedPayment } for _, h := range payment.InFlightHTLCs() { @@ -489,7 +363,7 @@ func (p *KVPaymentsDB) RegisterAttempt(paymentHash lntypes.Hash, // If this is a blinded payment, then no existing HTLCs // should have MPP records. if isBlinded && hMpp != nil { - return ErrMPPRecordInBlindedPayment + return paymentsdb.ErrMPPRecordInBlindedPayment } // If this is a blinded payment, then we just need to @@ -501,7 +375,7 @@ func (p *KVPaymentsDB) RegisterAttempt(paymentHash lntypes.Hash, h.Route.FinalHop().TotalAmtMsat { //nolint:ll - return ErrBlindedPaymentTotalAmountMismatch + return paymentsdb.ErrBlindedPaymentTotalAmountMismatch } continue @@ -511,12 +385,12 @@ func (p *KVPaymentsDB) RegisterAttempt(paymentHash lntypes.Hash, // We tried to register a non-MPP attempt for a MPP // payment. case mpp == nil && hMpp != nil: - return ErrMPPayment + return paymentsdb.ErrMPPayment // We tried to register a MPP shard for a non-MPP // payment. case mpp != nil && hMpp == nil: - return ErrNonMPPayment + return paymentsdb.ErrNonMPPayment // Non-MPP payment, nothing more to validate. case mpp == nil: @@ -525,11 +399,11 @@ func (p *KVPaymentsDB) RegisterAttempt(paymentHash lntypes.Hash, // Check that MPP options match. if mpp.PaymentAddr() != hMpp.PaymentAddr() { - return ErrMPPPaymentAddrMismatch + return paymentsdb.ErrMPPPaymentAddrMismatch } if mpp.TotalMsat() != hMpp.TotalMsat() { - return ErrMPPTotalAmountMismatch + return paymentsdb.ErrMPPTotalAmountMismatch } } @@ -538,15 +412,15 @@ func (p *KVPaymentsDB) RegisterAttempt(paymentHash lntypes.Hash, // attempt. amt := attempt.Route.ReceiverAmt() if !isBlinded && mpp == nil && amt != payment.Info.Value { - return ErrValueMismatch + return paymentsdb.ErrValueMismatch } // Ensure we aren't sending more than the total payment amount. sentAmt, _ := payment.SentAmt() if sentAmt+amt > payment.Info.Value { return fmt.Errorf("%w: attempted=%v, payment amount="+ - "%v", ErrValueExceedsAmt, sentAmt+amt, - payment.Info.Value) + "%v", paymentsdb.ErrValueExceedsAmt, + sentAmt+amt, payment.Info.Value) } htlcsBucket, err := bucket.CreateBucketIfNotExists( @@ -651,12 +525,12 @@ func (p *KVPaymentsDB) updateHtlcKey(paymentHash lntypes.Hash, // Make sure the shard is not already failed or settled. failKey := htlcBucketKey(htlcFailInfoKey, aid) if htlcsBucket.Get(failKey) != nil { - return ErrAttemptAlreadyFailed + return paymentsdb.ErrAttemptAlreadyFailed } settleKey := htlcBucketKey(htlcSettleInfoKey, aid) if htlcsBucket.Get(settleKey) != nil { - return ErrAttemptAlreadySettled + return paymentsdb.ErrAttemptAlreadySettled } // Add or update the key for this htlc. @@ -696,8 +570,8 @@ func (p *KVPaymentsDB) Fail(paymentHash lntypes.Hash, prefetchPayment(tx, paymentHash) bucket, err := fetchPaymentBucketUpdate(tx, paymentHash) - if errors.Is(err, ErrPaymentNotInitiated) { - updateErr = ErrPaymentNotInitiated + if errors.Is(err, paymentsdb.ErrPaymentNotInitiated) { + updateErr = paymentsdb.ErrPaymentNotInitiated return nil } else if err != nil { return err @@ -708,8 +582,8 @@ func (p *KVPaymentsDB) Fail(paymentHash lntypes.Hash, // failure to the KVPaymentsDB without synchronizing with // other attempts. _, err = fetchPaymentStatus(bucket) - if errors.Is(err, ErrPaymentNotInitiated) { - updateErr = ErrPaymentNotInitiated + if errors.Is(err, paymentsdb.ErrPaymentNotInitiated) { + updateErr = paymentsdb.ErrPaymentNotInitiated return nil } else if err != nil { return err @@ -802,12 +676,12 @@ func fetchPaymentBucket(tx kvdb.RTx, paymentHash lntypes.Hash) ( payments := tx.ReadBucket(paymentsRootBucket) if payments == nil { - return nil, ErrPaymentNotInitiated + return nil, paymentsdb.ErrPaymentNotInitiated } bucket := payments.NestedReadBucket(paymentHash[:]) if bucket == nil { - return nil, ErrPaymentNotInitiated + return nil, paymentsdb.ErrPaymentNotInitiated } return bucket, nil @@ -820,12 +694,12 @@ func fetchPaymentBucketUpdate(tx kvdb.RwTx, paymentHash lntypes.Hash) ( payments := tx.ReadWriteBucket(paymentsRootBucket) if payments == nil { - return nil, ErrPaymentNotInitiated + return nil, paymentsdb.ErrPaymentNotInitiated } bucket := payments.NestedReadWriteBucket(paymentHash[:]) if bucket == nil { - return nil, ErrPaymentNotInitiated + return nil, paymentsdb.ErrPaymentNotInitiated } return bucket, nil @@ -882,7 +756,7 @@ func fetchPaymentStatus(bucket kvdb.RBucket) (PaymentStatus, error) { // Creation info should be set for all payments, regardless of state. // If not, it is unknown. if bucket.Get(paymentCreationInfoKey) == nil { - return 0, ErrPaymentNotInitiated + return 0, paymentsdb.ErrPaymentNotInitiated } payment, err := fetchPayment(bucket) @@ -1128,7 +1002,7 @@ func fetchHtlcAttempts(bucket kvdb.RBucket) ([]HTLCAttempt, error) { // Sanity check that all htlcs have an attempt info. if attemptInfoCount != len(htlcsMap) { - return nil, errNoAttemptInfo + return nil, paymentsdb.ErrNoAttemptInfo } keys := make([]uint64, len(htlcsMap)) @@ -1367,7 +1241,7 @@ func fetchPaymentWithSequenceNumber(tx kvdb.RTx, paymentHash lntypes.Hash, // the payment we are actually looking for. seqBytes := bucket.Get(paymentSequenceKey) if seqBytes == nil { - return nil, ErrNoSequenceNumber + return nil, paymentsdb.ErrNoSequenceNumber } // If this top level payment has the sequence number we are looking for, @@ -1382,7 +1256,7 @@ func fetchPaymentWithSequenceNumber(tx kvdb.RTx, paymentHash lntypes.Hash, // find a duplicate payments bucket here, something is wrong. dup := bucket.NestedReadBucket(duplicatePaymentsBucket) if dup == nil { - return nil, ErrNoDuplicateBucket + return nil, paymentsdb.ErrNoDuplicateBucket } var duplicatePayment *MPPayment @@ -1390,7 +1264,7 @@ func fetchPaymentWithSequenceNumber(tx kvdb.RTx, paymentHash lntypes.Hash, subBucket := dup.NestedReadBucket(k) if subBucket == nil { // We one bucket for each duplicate to be found. - return ErrNoDuplicateNestedBucket + return paymentsdb.ErrNoDuplicateNestedBucket } seqBytes := subBucket.Get(duplicatePaymentSequenceKey) @@ -1419,7 +1293,7 @@ func fetchPaymentWithSequenceNumber(tx kvdb.RTx, paymentHash lntypes.Hash, // failed to find the payment with this sequence number; something is // wrong. if duplicatePayment == nil { - return nil, ErrDuplicateNotFound + return nil, paymentsdb.ErrDuplicateNotFound } return duplicatePayment, nil diff --git a/channeldb/payments_kv_store_test.go b/channeldb/payments_kv_store_test.go index 3e825597d..4083fa327 100644 --- a/channeldb/payments_kv_store_test.go +++ b/channeldb/payments_kv_store_test.go @@ -16,6 +16,7 @@ import ( "github.com/lightningnetwork/lnd/kvdb" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/tlv" @@ -193,7 +194,7 @@ func TestKVPaymentsDBSwitchFail(t *testing.T) { // Attempt a final payment, which should now fail since the prior // payment succeed. err = paymentDB.InitPayment(info.PaymentIdentifier, info) - if !errors.Is(err, ErrAlreadyPaid) { + if !errors.Is(err, paymentsdb.ErrAlreadyPaid) { t.Fatalf("unable to send htlc message: %v", err) } } @@ -228,7 +229,7 @@ func TestKVPaymentsDBSwitchDoubleSend(t *testing.T) { // payment hash, should result in error indicating that payment has // already been sent. err = paymentDB.InitPayment(info.PaymentIdentifier, info) - require.ErrorIs(t, err, ErrPaymentExists) + require.ErrorIs(t, err, paymentsdb.ErrPaymentExists) // Record an attempt. _, err = paymentDB.RegisterAttempt(info.PaymentIdentifier, attempt) @@ -246,7 +247,7 @@ func TestKVPaymentsDBSwitchDoubleSend(t *testing.T) { // Sends base htlc message which initiate StatusInFlight. err = paymentDB.InitPayment(info.PaymentIdentifier, info) - if !errors.Is(err, ErrPaymentInFlight) { + if !errors.Is(err, paymentsdb.ErrPaymentInFlight) { t.Fatalf("payment control wrong behaviour: " + "double sending must trigger ErrPaymentInFlight error") } @@ -269,7 +270,7 @@ func TestKVPaymentsDBSwitchDoubleSend(t *testing.T) { ) err = paymentDB.InitPayment(info.PaymentIdentifier, info) - if !errors.Is(err, ErrAlreadyPaid) { + if !errors.Is(err, paymentsdb.ErrAlreadyPaid) { t.Fatalf("unable to send htlc message: %v", err) } } @@ -294,9 +295,7 @@ func TestKVPaymentsDBSuccessesWithoutInFlight(t *testing.T) { Preimage: preimg, }, ) - if err != ErrPaymentNotInitiated { - t.Fatalf("expected ErrPaymentNotInitiated, got %v", err) - } + require.ErrorIs(t, err, paymentsdb.ErrPaymentNotInitiated) } // TestKVPaymentsDBFailsWithoutInFlight checks that a strict payment @@ -314,9 +313,7 @@ func TestKVPaymentsDBFailsWithoutInFlight(t *testing.T) { // Calling Fail should return an error. _, err = paymentDB.Fail(info.PaymentIdentifier, FailureReasonNoRoute) - if err != ErrPaymentNotInitiated { - t.Fatalf("expected ErrPaymentNotInitiated, got %v", err) - } + require.ErrorIs(t, err, paymentsdb.ErrPaymentNotInitiated) } // TestKVPaymentsDBDeleteNonInFlight checks that calling DeletePayments only @@ -780,7 +777,7 @@ func TestKVPaymentsDBMultiShard(t *testing.T) { b := *attempt b.AttemptID = 3 _, err = paymentDB.RegisterAttempt(info.PaymentIdentifier, &b) - require.ErrorIs(t, err, ErrValueExceedsAmt) + require.ErrorIs(t, err, paymentsdb.ErrValueExceedsAmt) // Fail the second attempt. a := attempts[1] @@ -880,9 +877,13 @@ func TestKVPaymentsDBMultiShard(t *testing.T) { b.AttemptID = 3 _, err = paymentDB.RegisterAttempt(info.PaymentIdentifier, &b) if test.settleFirst { - require.ErrorIs(t, err, ErrPaymentPendingSettled) + require.ErrorIs( + t, err, paymentsdb.ErrPaymentPendingSettled, + ) } else { - require.ErrorIs(t, err, ErrPaymentPendingFailed) + require.ErrorIs( + t, err, paymentsdb.ErrPaymentPendingFailed, + ) } assertPaymentStatus( @@ -951,21 +952,21 @@ func TestKVPaymentsDBMultiShard(t *testing.T) { // settled. case test.settleFirst && !test.settleLast: finalStatus = StatusSucceeded - registerErr = ErrPaymentAlreadySucceeded + registerErr = paymentsdb.ErrPaymentAlreadySucceeded case !test.settleFirst && test.settleLast: finalStatus = StatusSucceeded - registerErr = ErrPaymentAlreadySucceeded + registerErr = paymentsdb.ErrPaymentAlreadySucceeded // If both failed, we end up in a failed status. case !test.settleFirst && !test.settleLast: finalStatus = StatusFailed - registerErr = ErrPaymentAlreadyFailed + registerErr = paymentsdb.ErrPaymentAlreadyFailed // Otherwise, the payment has a succeed status. case test.settleFirst && test.settleLast: finalStatus = StatusSucceeded - registerErr = ErrPaymentAlreadySucceeded + registerErr = paymentsdb.ErrPaymentAlreadySucceeded } assertPaymentStatus( @@ -1021,27 +1022,21 @@ func TestKVPaymentsDBMPPRecordValidation(t *testing.T) { b.AttemptID = 1 b.Route.FinalHop().MPP = nil _, err = paymentDB.RegisterAttempt(info.PaymentIdentifier, &b) - if err != ErrMPPayment { - t.Fatalf("expected ErrMPPayment, got: %v", err) - } + require.ErrorIs(t, err, paymentsdb.ErrMPPayment) // Try to register attempt one with a different payment address. b.Route.FinalHop().MPP = record.NewMPP( info.Value, [32]byte{2}, ) _, err = paymentDB.RegisterAttempt(info.PaymentIdentifier, &b) - if err != ErrMPPPaymentAddrMismatch { - t.Fatalf("expected ErrMPPPaymentAddrMismatch, got: %v", err) - } + require.ErrorIs(t, err, paymentsdb.ErrMPPPaymentAddrMismatch) // Try registering one with a different total amount. b.Route.FinalHop().MPP = record.NewMPP( info.Value/2, [32]byte{1}, ) _, err = paymentDB.RegisterAttempt(info.PaymentIdentifier, &b) - if err != ErrMPPTotalAmountMismatch { - t.Fatalf("expected ErrMPPTotalAmountMismatch, got: %v", err) - } + require.ErrorIs(t, err, paymentsdb.ErrMPPTotalAmountMismatch) // Create and init a new payment. This time we'll check that we cannot // register an MPP attempt if we already registered a non-MPP one. @@ -1063,9 +1058,7 @@ func TestKVPaymentsDBMPPRecordValidation(t *testing.T) { ) _, err = paymentDB.RegisterAttempt(info.PaymentIdentifier, &b) - if err != ErrNonMPPayment { - t.Fatalf("expected ErrNonMPPayment, got: %v", err) - } + require.ErrorIs(t, err, paymentsdb.ErrNonMPPayment) } // TestDeleteFailedAttempts checks that DeleteFailedAttempts properly removes @@ -1171,7 +1164,7 @@ func assertPaymentStatus(t *testing.T, p *KVPaymentsDB, t.Helper() payment, err := p.FetchPayment(hash) - if errors.Is(err, ErrPaymentNotInitiated) { + if errors.Is(err, paymentsdb.ErrPaymentNotInitiated) { return } if err != nil { @@ -1271,7 +1264,7 @@ func fetchPaymentIndexEntry(_ *testing.T, p *KVPaymentsDB, indexValue := indexBucket.Get(key) if indexValue == nil { - return errNoSequenceNrIndex + return paymentsdb.ErrNoSequenceNrIndex } r := bytes.NewReader(indexValue) @@ -1307,7 +1300,7 @@ func assertPaymentIndex(t *testing.T, p *KVPaymentsDB, // exist. func assertNoIndex(t *testing.T, p *KVPaymentsDB, seqNr uint64) { _, err := fetchPaymentIndexEntry(t, p, seqNr) - require.Equal(t, errNoSequenceNrIndex, err) + require.Equal(t, paymentsdb.ErrNoSequenceNrIndex, err) } // payment is a helper structure that holds basic information on a test payment, @@ -1669,14 +1662,14 @@ func TestFetchPaymentWithSequenceNumber(t *testing.T) { name: "lookup non-existent duplicate", paymentHash: hasDuplicates.PaymentIdentifier, sequenceNumber: 999999, - expectedErr: ErrDuplicateNotFound, + expectedErr: paymentsdb.ErrDuplicateNotFound, }, { name: "lookup duplicate, no duplicates " + "bucket", paymentHash: noDuplicates.PaymentIdentifier, sequenceNumber: duplicateTwoSeqNr, - expectedErr: ErrNoDuplicateBucket, + expectedErr: paymentsdb.ErrNoDuplicateBucket, }, } diff --git a/lnrpc/routerrpc/router_server.go b/lnrpc/routerrpc/router_server.go index 2e65aed70..843222eee 100644 --- a/lnrpc/routerrpc/router_server.go +++ b/lnrpc/routerrpc/router_server.go @@ -22,6 +22,7 @@ import ( "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" "github.com/lightningnetwork/lnd/macaroons" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/routing" "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/zpay32" @@ -373,9 +374,9 @@ func (s *Server) SendPaymentV2(req *SendPaymentRequest, payment.Identifier(), err) // Transform user errors to grpc code. - if errors.Is(err, channeldb.ErrPaymentExists) || - errors.Is(err, channeldb.ErrPaymentInFlight) || - errors.Is(err, channeldb.ErrAlreadyPaid) { + if errors.Is(err, paymentsdb.ErrPaymentExists) || + errors.Is(err, paymentsdb.ErrPaymentInFlight) || + errors.Is(err, paymentsdb.ErrAlreadyPaid) { return status.Error( codes.AlreadyExists, err.Error(), @@ -955,13 +956,13 @@ func (s *Server) SendToRouteV2(ctx context.Context, // Transform user errors to grpc code. switch { - case errors.Is(err, channeldb.ErrPaymentExists): + case errors.Is(err, paymentsdb.ErrPaymentExists): fallthrough - case errors.Is(err, channeldb.ErrPaymentInFlight): + case errors.Is(err, paymentsdb.ErrPaymentInFlight): fallthrough - case errors.Is(err, channeldb.ErrAlreadyPaid): + case errors.Is(err, paymentsdb.ErrAlreadyPaid): return nil, status.Error( codes.AlreadyExists, err.Error(), ) @@ -1368,7 +1369,7 @@ func (s *Server) subscribePayment(identifier lntypes.Hash) ( sub, err := router.Tower.SubscribePayment(identifier) switch { - case errors.Is(err, channeldb.ErrPaymentNotInitiated): + case errors.Is(err, paymentsdb.ErrPaymentNotInitiated): return nil, status.Error(codes.NotFound, err.Error()) case err != nil: diff --git a/payments/db/errors.go b/payments/db/errors.go new file mode 100644 index 000000000..40e37d95c --- /dev/null +++ b/payments/db/errors.go @@ -0,0 +1,133 @@ +package paymentsdb + +import "errors" + +var ( + // ErrAlreadyPaid signals we have already paid this payment hash. + ErrAlreadyPaid = errors.New("invoice is already paid") + + // ErrPaymentInFlight signals that payment for this payment hash is + // already "in flight" on the network. + ErrPaymentInFlight = errors.New("payment is in transition") + + // ErrPaymentExists is returned when we try to initialize an already + // existing payment that is not failed. + ErrPaymentExists = errors.New("payment already exists") + + // ErrPaymentInternal is returned when performing the payment has a + // conflicting state, such as, + // - payment has StatusSucceeded but remaining amount is not zero. + // - payment has StatusInitiated but remaining amount is zero. + // - payment has StatusFailed but remaining amount is zero. + ErrPaymentInternal = errors.New("internal error") + + // ErrPaymentNotInitiated is returned if the payment wasn't initiated. + ErrPaymentNotInitiated = errors.New("payment isn't initiated") + + // ErrPaymentAlreadySucceeded is returned in the event we attempt to + // change the status of a payment already succeeded. + ErrPaymentAlreadySucceeded = errors.New("payment is already succeeded") + + // ErrPaymentAlreadyFailed is returned in the event we attempt to alter + // a failed payment. + ErrPaymentAlreadyFailed = errors.New("payment has already failed") + + // ErrUnknownPaymentStatus is returned when we do not recognize the + // existing state of a payment. + ErrUnknownPaymentStatus = errors.New("unknown payment status") + + // ErrPaymentTerminal is returned if we attempt to alter a payment that + // already has reached a terminal condition. + ErrPaymentTerminal = errors.New("payment has reached terminal " + + "condition") + + // ErrAttemptAlreadySettled is returned if we try to alter an already + // settled HTLC attempt. + ErrAttemptAlreadySettled = errors.New("attempt already settled") + + // ErrAttemptAlreadyFailed is returned if we try to alter an already + // failed HTLC attempt. + ErrAttemptAlreadyFailed = errors.New("attempt already failed") + + // ErrValueMismatch is returned if we try to register a non-MPP attempt + // with an amount that doesn't match the payment amount. + ErrValueMismatch = errors.New("attempted value doesn't match payment " + + "amount") + + // ErrValueExceedsAmt is returned if we try to register an attempt that + // would take the total sent amount above the payment amount. + ErrValueExceedsAmt = errors.New("attempted value exceeds payment " + + "amount") + + // ErrNonMPPayment is returned if we try to register an MPP attempt for + // a payment that already has a non-MPP attempt registered. + ErrNonMPPayment = errors.New("payment has non-MPP attempts") + + // ErrMPPayment is returned if we try to register a non-MPP attempt for + // a payment that already has an MPP attempt registered. + ErrMPPayment = errors.New("payment has MPP attempts") + + // ErrMPPRecordInBlindedPayment is returned if we try to register an + // attempt with an MPP record for a payment to a blinded path. + ErrMPPRecordInBlindedPayment = errors.New("blinded payment cannot " + + "contain MPP records") + + // ErrBlindedPaymentTotalAmountMismatch is returned if we try to + // register an HTLC shard to a blinded route where the total amount + // doesn't match existing shards. + ErrBlindedPaymentTotalAmountMismatch = errors.New("blinded path " + + "total amount mismatch") + + // ErrMPPPaymentAddrMismatch is returned if we try to register an MPP + // shard where the payment address doesn't match existing shards. + ErrMPPPaymentAddrMismatch = errors.New("payment address mismatch") + + // ErrMPPTotalAmountMismatch is returned if we try to register an MPP + // shard where the total amount doesn't match existing shards. + ErrMPPTotalAmountMismatch = errors.New("mp payment total amount " + + "mismatch") + + // ErrPaymentPendingSettled is returned when we try to add a new + // attempt to a payment that has at least one of its HTLCs settled. + ErrPaymentPendingSettled = errors.New("payment has settled htlcs") + + // ErrPaymentPendingFailed is returned when we try to add a new attempt + // to a payment that already has a failure reason. + ErrPaymentPendingFailed = errors.New("payment has failure reason") + + // ErrSentExceedsTotal is returned if the payment's current total sent + // amount exceed the total amount. + ErrSentExceedsTotal = errors.New("total sent exceeds total amount") + + // ErrNoAttemptInfo is returned when no attempt info is stored yet. + ErrNoAttemptInfo = errors.New("unable to find attempt info for " + + "inflight payment") +) + +// KV backend specific errors. +var ( + // ErrNoSequenceNumber is returned if we look up a payment which does + // not have a sequence number. + ErrNoSequenceNumber = errors.New("sequence number not found") + + // ErrDuplicateNotFound is returned when we lookup a payment by its + // index and cannot find a payment with a matching sequence number. + ErrDuplicateNotFound = errors.New("duplicate payment not found") + + // ErrNoDuplicateBucket is returned when we expect to find duplicates + // when looking up a payment from its index, but the payment does not + // have any. + ErrNoDuplicateBucket = errors.New("expected duplicate bucket") + + // ErrNoDuplicateNestedBucket is returned if we do not find duplicate + // payments in their own sub-bucket. + ErrNoDuplicateNestedBucket = errors.New("nested duplicate bucket not " + + "found") + + // ErrNoSequenceNrIndex is returned when an attempt to lookup a payment + // index is made for a sequence number that is not indexed. + // + // NOTE: Only used for the kv backend. + ErrNoSequenceNrIndex = errors.New("payment sequence number index " + + "does not exist") +) diff --git a/routing/control_tower_test.go b/routing/control_tower_test.go index 697fa74d5..ceb5cb64f 100644 --- a/routing/control_tower_test.go +++ b/routing/control_tower_test.go @@ -13,6 +13,7 @@ import ( "github.com/davecgh/go-spew/spew" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lntypes" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/routing/route" "github.com/stretchr/testify/require" ) @@ -53,7 +54,7 @@ func TestControlTowerSubscribeUnknown(t *testing.T) { // Subscription should fail when the payment is not known. _, err := pControl.SubscribePayment(lntypes.Hash{1}) - require.ErrorIs(t, err, channeldb.ErrPaymentNotInitiated) + require.ErrorIs(t, err, paymentsdb.ErrPaymentNotInitiated) } // TestControlTowerSubscribeSuccess tests that payment updates for a diff --git a/routing/mock_test.go b/routing/mock_test.go index d3601636c..d9528254e 100644 --- a/routing/mock_test.go +++ b/routing/mock_test.go @@ -13,6 +13,7 @@ import ( "github.com/lightningnetwork/lnd/htlcswitch" "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/routing/shards" @@ -308,7 +309,7 @@ func (m *mockControlTowerOld) InitPayment(phash lntypes.Hash, // Don't allow re-init a successful payment. if _, ok := m.successful[phash]; ok { - return channeldb.ErrAlreadyPaid + return paymentsdb.ErrAlreadyPaid } _, failed := m.failed[phash] @@ -316,7 +317,7 @@ func (m *mockControlTowerOld) InitPayment(phash lntypes.Hash, // If the payment is known, only allow re-init if failed. if ok && !failed { - return channeldb.ErrPaymentInFlight + return paymentsdb.ErrPaymentInFlight } delete(m.failed, phash) @@ -330,7 +331,7 @@ func (m *mockControlTowerOld) InitPayment(phash lntypes.Hash, func (m *mockControlTowerOld) DeleteFailedAttempts(phash lntypes.Hash) error { p, ok := m.payments[phash] if !ok { - return channeldb.ErrPaymentNotInitiated + return paymentsdb.ErrPaymentNotInitiated } var inFlight bool @@ -347,7 +348,7 @@ func (m *mockControlTowerOld) DeleteFailedAttempts(phash lntypes.Hash) error { } if inFlight { - return channeldb.ErrPaymentInFlight + return paymentsdb.ErrPaymentInFlight } return nil @@ -366,7 +367,7 @@ func (m *mockControlTowerOld) RegisterAttempt(phash lntypes.Hash, // Lookup payment. p, ok := m.payments[phash] if !ok { - return channeldb.ErrPaymentNotInitiated + return paymentsdb.ErrPaymentNotInitiated } var inFlight bool @@ -387,15 +388,15 @@ func (m *mockControlTowerOld) RegisterAttempt(phash lntypes.Hash, _, failed := m.failed[phash] if settled || failed { - return channeldb.ErrPaymentTerminal + return paymentsdb.ErrPaymentTerminal } if settled && !inFlight { - return channeldb.ErrPaymentAlreadySucceeded + return paymentsdb.ErrPaymentAlreadySucceeded } if failed && !inFlight { - return channeldb.ErrPaymentAlreadyFailed + return paymentsdb.ErrPaymentAlreadyFailed } // Add attempt to payment. @@ -421,7 +422,7 @@ func (m *mockControlTowerOld) SettleAttempt(phash lntypes.Hash, // Only allow setting attempts if the payment is known. p, ok := m.payments[phash] if !ok { - return nil, channeldb.ErrPaymentNotInitiated + return nil, paymentsdb.ErrPaymentNotInitiated } // Find the attempt with this pid, and set the settle info. @@ -431,10 +432,10 @@ func (m *mockControlTowerOld) SettleAttempt(phash lntypes.Hash, } if a.Settle != nil { - return nil, channeldb.ErrAttemptAlreadySettled + return nil, paymentsdb.ErrAttemptAlreadySettled } if a.Failure != nil { - return nil, channeldb.ErrAttemptAlreadyFailed + return nil, paymentsdb.ErrAttemptAlreadyFailed } p.attempts[i].Settle = settleInfo @@ -462,7 +463,7 @@ func (m *mockControlTowerOld) FailAttempt(phash lntypes.Hash, pid uint64, // Only allow failing attempts if the payment is known. p, ok := m.payments[phash] if !ok { - return nil, channeldb.ErrPaymentNotInitiated + return nil, paymentsdb.ErrPaymentNotInitiated } // Find the attempt with this pid, and set the failure info. @@ -472,10 +473,10 @@ func (m *mockControlTowerOld) FailAttempt(phash lntypes.Hash, pid uint64, } if a.Settle != nil { - return nil, channeldb.ErrAttemptAlreadySettled + return nil, paymentsdb.ErrAttemptAlreadySettled } if a.Failure != nil { - return nil, channeldb.ErrAttemptAlreadyFailed + return nil, paymentsdb.ErrAttemptAlreadyFailed } p.attempts[i].Failure = failInfo @@ -499,7 +500,7 @@ func (m *mockControlTowerOld) FailPayment(phash lntypes.Hash, // Payment must be known. if _, ok := m.payments[phash]; !ok { - return channeldb.ErrPaymentNotInitiated + return paymentsdb.ErrPaymentNotInitiated } m.failed[phash] = reason @@ -521,7 +522,7 @@ func (m *mockControlTowerOld) fetchPayment(phash lntypes.Hash) ( p, ok := m.payments[phash] if !ok { - return nil, channeldb.ErrPaymentNotInitiated + return nil, paymentsdb.ErrPaymentNotInitiated } mp := &channeldb.MPPayment{ diff --git a/routing/router.go b/routing/router.go index dcece2566..f7347c86f 100644 --- a/routing/router.go +++ b/routing/router.go @@ -24,6 +24,7 @@ import ( "github.com/lightningnetwork/lnd/lnutils" "github.com/lightningnetwork/lnd/lnwallet" "github.com/lightningnetwork/lnd/lnwire" + paymentsdb "github.com/lightningnetwork/lnd/payments/db" "github.com/lightningnetwork/lnd/record" "github.com/lightningnetwork/lnd/routing/route" "github.com/lightningnetwork/lnd/routing/shards" @@ -1133,8 +1134,8 @@ func (r *ChannelRouter) sendToRoute(htlcHash lntypes.Hash, rt *route.Route, switch { // If this is an MPP attempt and the hash is already registered with // the database, we can go on to launch the shard. - case mpp != nil && errors.Is(err, channeldb.ErrPaymentInFlight): - case mpp != nil && errors.Is(err, channeldb.ErrPaymentExists): + case mpp != nil && errors.Is(err, paymentsdb.ErrPaymentInFlight): + case mpp != nil && errors.Is(err, paymentsdb.ErrPaymentExists): // Any other error is not tolerated. case err != nil: