multi: move payment related code into own package

This commit moves most of the code into its own package. It is
the smallest code move possible without moving import cycles and
keeping the changes to the code base as small as possible during
refactor.
This commit is contained in:
ziggie
2025-08-13 09:19:20 +02:00
parent 77a6b577eb
commit 03af9858d2
26 changed files with 1075 additions and 948 deletions

View File

@@ -6,6 +6,7 @@ import (
"github.com/lightningnetwork/lnd/channeldb"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/multimutex"
paymentsdb "github.com/lightningnetwork/lnd/payments/db"
"github.com/lightningnetwork/lnd/queue"
)
@@ -13,23 +14,23 @@ import (
// the payment lifecycle.
type DBMPPayment interface {
// GetState returns the current state of the payment.
GetState() *channeldb.MPPaymentState
GetState() *paymentsdb.MPPaymentState
// Terminated returns true if the payment is in a final state.
Terminated() bool
// GetStatus returns the current status of the payment.
GetStatus() channeldb.PaymentStatus
GetStatus() paymentsdb.PaymentStatus
// NeedWaitAttempts specifies whether the payment needs to wait for the
// outcome of an attempt.
NeedWaitAttempts() (bool, error)
// GetHTLCs returns all HTLCs of this payment.
GetHTLCs() []channeldb.HTLCAttempt
GetHTLCs() []paymentsdb.HTLCAttempt
// InFlightHTLCs returns all HTLCs that are in flight.
InFlightHTLCs() []channeldb.HTLCAttempt
InFlightHTLCs() []paymentsdb.HTLCAttempt
// AllowMoreAttempts is used to decide whether we can safely attempt
// more HTLCs for a given payment state. Return an error if the payment
@@ -38,7 +39,7 @@ type DBMPPayment interface {
// TerminalInfo returns the settled HTLC attempt or the payment's
// failure reason.
TerminalInfo() (*channeldb.HTLCAttempt, *channeldb.FailureReason)
TerminalInfo() (*paymentsdb.HTLCAttempt, *channeldb.FailureReason)
}
// ControlTower tracks all outgoing payments made, whose primary purpose is to
@@ -57,7 +58,7 @@ type ControlTower interface {
DeleteFailedAttempts(lntypes.Hash) error
// RegisterAttempt atomically records the provided HTLCAttemptInfo.
RegisterAttempt(lntypes.Hash, *channeldb.HTLCAttemptInfo) error
RegisterAttempt(lntypes.Hash, *paymentsdb.HTLCAttemptInfo) error
// SettleAttempt marks the given attempt settled with the preimage. If
// this is a multi shard payment, this might implicitly mean the the
@@ -67,12 +68,12 @@ type ControlTower interface {
// error to prevent us from making duplicate payments to the same
// payment hash. The provided preimage is atomically saved to the DB
// for record keeping.
SettleAttempt(lntypes.Hash, uint64, *channeldb.HTLCSettleInfo) (
*channeldb.HTLCAttempt, error)
SettleAttempt(lntypes.Hash, uint64, *paymentsdb.HTLCSettleInfo) (
*paymentsdb.HTLCAttempt, error)
// FailAttempt marks the given payment attempt failed.
FailAttempt(lntypes.Hash, uint64, *channeldb.HTLCFailInfo) (
*channeldb.HTLCAttempt, error)
FailAttempt(lntypes.Hash, uint64, *paymentsdb.HTLCFailInfo) (
*paymentsdb.HTLCAttempt, error)
// FetchPayment fetches the payment corresponding to the given payment
// hash.
@@ -87,7 +88,7 @@ type ControlTower interface {
FailPayment(lntypes.Hash, channeldb.FailureReason) error
// FetchInFlightPayments returns all payments with status InFlight.
FetchInFlightPayments() ([]*channeldb.MPPayment, error)
FetchInFlightPayments() ([]*paymentsdb.MPPayment, error)
// SubscribePayment subscribes to updates for the payment with the given
// hash. A first update with the current state of the payment is always
@@ -151,7 +152,7 @@ func (s *controlTowerSubscriberImpl) Updates() <-chan interface{} {
// controlTower is persistent implementation of ControlTower to restrict
// double payment sending.
type controlTower struct {
db *channeldb.KVPaymentsDB
db *paymentsdb.KVPaymentsDB
// subscriberIndex is used to provide a unique id for each subscriber
// to all payments. This is used to easily remove the subscriber when
@@ -168,7 +169,7 @@ type controlTower struct {
}
// NewControlTower creates a new instance of the controlTower.
func NewControlTower(db *channeldb.KVPaymentsDB) ControlTower {
func NewControlTower(db *paymentsdb.KVPaymentsDB) ControlTower {
return &controlTower{
db: db,
subscribersAllPayments: make(
@@ -215,7 +216,7 @@ func (p *controlTower) DeleteFailedAttempts(paymentHash lntypes.Hash) error {
// RegisterAttempt atomically records the provided HTLCAttemptInfo to the
// DB.
func (p *controlTower) RegisterAttempt(paymentHash lntypes.Hash,
attempt *channeldb.HTLCAttemptInfo) error {
attempt *paymentsdb.HTLCAttemptInfo) error {
p.paymentsMtx.Lock(paymentHash)
defer p.paymentsMtx.Unlock(paymentHash)
@@ -235,8 +236,8 @@ func (p *controlTower) RegisterAttempt(paymentHash lntypes.Hash,
// this is a multi shard payment, this might implicitly mean the the
// full payment succeeded.
func (p *controlTower) SettleAttempt(paymentHash lntypes.Hash,
attemptID uint64, settleInfo *channeldb.HTLCSettleInfo) (
*channeldb.HTLCAttempt, error) {
attemptID uint64, settleInfo *paymentsdb.HTLCSettleInfo) (
*paymentsdb.HTLCAttempt, error) {
p.paymentsMtx.Lock(paymentHash)
defer p.paymentsMtx.Unlock(paymentHash)
@@ -254,8 +255,8 @@ func (p *controlTower) SettleAttempt(paymentHash lntypes.Hash,
// FailAttempt marks the given payment attempt failed.
func (p *controlTower) FailAttempt(paymentHash lntypes.Hash,
attemptID uint64, failInfo *channeldb.HTLCFailInfo) (
*channeldb.HTLCAttempt, error) {
attemptID uint64, failInfo *paymentsdb.HTLCFailInfo) (
*paymentsdb.HTLCAttempt, error) {
p.paymentsMtx.Lock(paymentHash)
defer p.paymentsMtx.Unlock(paymentHash)
@@ -303,7 +304,9 @@ func (p *controlTower) FailPayment(paymentHash lntypes.Hash,
}
// FetchInFlightPayments returns all payments with status InFlight.
func (p *controlTower) FetchInFlightPayments() ([]*channeldb.MPPayment, error) {
func (p *controlTower) FetchInFlightPayments() ([]*paymentsdb.MPPayment,
error) {
return p.db.FetchInFlightPayments()
}
@@ -386,7 +389,7 @@ func (p *controlTower) SubscribeAllPayments() (ControlTowerSubscriber, error) {
// be executed atomically (by means of a lock) with the database update to
// guarantee consistency of the notifications.
func (p *controlTower) notifySubscribers(paymentHash lntypes.Hash,
event *channeldb.MPPayment) {
event *paymentsdb.MPPayment) {
// Get all subscribers for this payment.
p.subscribersMtx.Lock()

View File

@@ -50,7 +50,7 @@ func TestControlTowerSubscribeUnknown(t *testing.T) {
db := initDB(t)
paymentDB, err := channeldb.NewKVPaymentsDB(
paymentDB, err := paymentsdb.NewKVPaymentsDB(
db,
paymentsdb.WithKeepFailedPaymentAttempts(true),
)
@@ -70,7 +70,7 @@ func TestControlTowerSubscribeSuccess(t *testing.T) {
db := initDB(t)
paymentDB, err := channeldb.NewKVPaymentsDB(db)
paymentDB, err := paymentsdb.NewKVPaymentsDB(db)
require.NoError(t, err)
pControl := NewControlTower(paymentDB)
@@ -102,7 +102,7 @@ func TestControlTowerSubscribeSuccess(t *testing.T) {
require.NoError(t, err, "expected subscribe to succeed, but got")
// Mark the payment as successful.
settleInfo := channeldb.HTLCSettleInfo{
settleInfo := paymentsdb.HTLCSettleInfo{
Preimage: preimg,
}
htlcAttempt, err := pControl.SettleAttempt(
@@ -126,19 +126,19 @@ func TestControlTowerSubscribeSuccess(t *testing.T) {
}
for i, s := range subscribers {
var result *channeldb.MPPayment
var result *paymentsdb.MPPayment
for result == nil || !result.Terminated() {
select {
case item := <-s.Updates():
result = item.(*channeldb.MPPayment)
result = item.(*paymentsdb.MPPayment)
case <-time.After(testTimeout):
t.Fatal("timeout waiting for payment result")
}
}
require.Equalf(t, channeldb.StatusSucceeded, result.GetStatus(),
require.Equalf(t, paymentsdb.StatusSucceeded, result.GetStatus(),
"subscriber %v failed, want %s, got %s", i,
channeldb.StatusSucceeded, result.GetStatus())
paymentsdb.StatusSucceeded, result.GetStatus())
attempt, _ := result.TerminalInfo()
if attempt.Settle.Preimage != preimg {
@@ -192,7 +192,7 @@ func TestKVPaymentsDBSubscribeAllSuccess(t *testing.T) {
db := initDB(t)
paymentDB, err := channeldb.NewKVPaymentsDB(
paymentDB, err := paymentsdb.NewKVPaymentsDB(
db,
paymentsdb.WithKeepFailedPaymentAttempts(true),
)
@@ -228,7 +228,7 @@ func TestKVPaymentsDBSubscribeAllSuccess(t *testing.T) {
require.NoError(t, err)
// Mark the first payment as successful.
settleInfo1 := channeldb.HTLCSettleInfo{
settleInfo1 := paymentsdb.HTLCSettleInfo{
Preimage: preimg1,
}
htlcAttempt1, err := pControl.SettleAttempt(
@@ -241,7 +241,7 @@ func TestKVPaymentsDBSubscribeAllSuccess(t *testing.T) {
)
// Mark the second payment as successful.
settleInfo2 := channeldb.HTLCSettleInfo{
settleInfo2 := paymentsdb.HTLCSettleInfo{
Preimage: preimg2,
}
htlcAttempt2, err := pControl.SettleAttempt(
@@ -255,14 +255,14 @@ func TestKVPaymentsDBSubscribeAllSuccess(t *testing.T) {
// The two payments will be asserted individually, store the last update
// for each payment.
results := make(map[lntypes.Hash]*channeldb.MPPayment)
results := make(map[lntypes.Hash]*paymentsdb.MPPayment)
// After exactly 6 updates both payments will/should have completed.
for i := 0; i < 6; i++ {
select {
case item := <-subscription.Updates():
id := item.(*channeldb.MPPayment).Info.PaymentIdentifier
results[id] = item.(*channeldb.MPPayment)
id := item.(*paymentsdb.MPPayment).Info.PaymentIdentifier
results[id] = item.(*paymentsdb.MPPayment)
case <-time.After(testTimeout):
require.Fail(t, "timeout waiting for payment result")
}
@@ -270,7 +270,7 @@ func TestKVPaymentsDBSubscribeAllSuccess(t *testing.T) {
result1 := results[info1.PaymentIdentifier]
require.Equal(
t, channeldb.StatusSucceeded, result1.GetStatus(),
t, paymentsdb.StatusSucceeded, result1.GetStatus(),
"unexpected payment state payment 1",
)
@@ -288,7 +288,7 @@ func TestKVPaymentsDBSubscribeAllSuccess(t *testing.T) {
result2 := results[info2.PaymentIdentifier]
require.Equal(
t, channeldb.StatusSucceeded, result2.GetStatus(),
t, paymentsdb.StatusSucceeded, result2.GetStatus(),
"unexpected payment state payment 2",
)
@@ -311,7 +311,7 @@ func TestKVPaymentsDBSubscribeAllImmediate(t *testing.T) {
db := initDB(t)
paymentDB, err := channeldb.NewKVPaymentsDB(
paymentDB, err := paymentsdb.NewKVPaymentsDB(
db,
paymentsdb.WithKeepFailedPaymentAttempts(true),
)
@@ -339,7 +339,7 @@ func TestKVPaymentsDBSubscribeAllImmediate(t *testing.T) {
require.NotNil(t, update)
require.Equal(
t, info.PaymentIdentifier,
update.(*channeldb.MPPayment).Info.PaymentIdentifier,
update.(*paymentsdb.MPPayment).Info.PaymentIdentifier,
)
require.Len(t, subscription.Updates(), 0)
case <-time.After(testTimeout):
@@ -354,7 +354,7 @@ func TestKVPaymentsDBUnsubscribeSuccess(t *testing.T) {
db := initDB(t)
paymentDB, err := channeldb.NewKVPaymentsDB(
paymentDB, err := paymentsdb.NewKVPaymentsDB(
db,
paymentsdb.WithKeepFailedPaymentAttempts(true),
)
@@ -411,8 +411,8 @@ func TestKVPaymentsDBUnsubscribeSuccess(t *testing.T) {
subscription2.Close()
// Register another update.
failInfo := channeldb.HTLCFailInfo{
Reason: channeldb.HTLCFailInternal,
failInfo := paymentsdb.HTLCFailInfo{
Reason: paymentsdb.HTLCFailInternal,
}
_, err = pControl.FailAttempt(
info.PaymentIdentifier, attempt.AttemptID, &failInfo,
@@ -429,7 +429,7 @@ func testKVPaymentsDBSubscribeFail(t *testing.T, registerAttempt,
db := initDB(t)
paymentDB, err := channeldb.NewKVPaymentsDB(
paymentDB, err := paymentsdb.NewKVPaymentsDB(
db,
paymentsdb.WithKeepFailedPaymentAttempts(
keepFailedPaymentAttempts,
@@ -465,8 +465,8 @@ func testKVPaymentsDBSubscribeFail(t *testing.T, registerAttempt,
}
// Fail the payment attempt.
failInfo := channeldb.HTLCFailInfo{
Reason: channeldb.HTLCFailInternal,
failInfo := paymentsdb.HTLCFailInfo{
Reason: paymentsdb.HTLCFailInternal,
}
htlcAttempt, err := pControl.FailAttempt(
info.PaymentIdentifier, attempt.AttemptID, &failInfo,
@@ -498,17 +498,17 @@ func testKVPaymentsDBSubscribeFail(t *testing.T, registerAttempt,
}
for i, s := range subscribers {
var result *channeldb.MPPayment
var result *paymentsdb.MPPayment
for result == nil || !result.Terminated() {
select {
case item := <-s.Updates():
result = item.(*channeldb.MPPayment)
result = item.(*paymentsdb.MPPayment)
case <-time.After(testTimeout):
t.Fatal("timeout waiting for payment result")
}
}
if result.GetStatus() == channeldb.StatusSucceeded {
if result.GetStatus() == paymentsdb.StatusSucceeded {
t.Fatal("unexpected payment state")
}
@@ -533,9 +533,9 @@ func testKVPaymentsDBSubscribeFail(t *testing.T, registerAttempt,
len(result.HTLCs))
}
require.Equalf(t, channeldb.StatusFailed, result.GetStatus(),
require.Equalf(t, paymentsdb.StatusFailed, result.GetStatus(),
"subscriber %v failed, want %s, got %s", i,
channeldb.StatusFailed, result.GetStatus())
paymentsdb.StatusFailed, result.GetStatus())
if *result.FailureReason != channeldb.FailureReasonTimeout {
t.Fatal("unexpected failure reason")
@@ -559,7 +559,7 @@ func initDB(t *testing.T) *channeldb.DB {
)
}
func genInfo() (*channeldb.PaymentCreationInfo, *channeldb.HTLCAttemptInfo,
func genInfo() (*channeldb.PaymentCreationInfo, *paymentsdb.HTLCAttemptInfo,
lntypes.Preimage, error) {
preimage, err := genPreimage()
@@ -572,7 +572,7 @@ func genInfo() (*channeldb.PaymentCreationInfo, *channeldb.HTLCAttemptInfo,
var hash lntypes.Hash
copy(hash[:], rhash[:])
attempt, err := channeldb.NewHtlcAttempt(
attempt, err := paymentsdb.NewHtlcAttempt(
1, priv, testRoute, time.Time{}, &hash,
)
if err != nil {

View File

@@ -252,7 +252,7 @@ type initArgs struct {
}
type registerAttemptArgs struct {
a *channeldb.HTLCAttemptInfo
a *paymentsdb.HTLCAttemptInfo
}
type settleAttemptArgs struct {
@@ -260,7 +260,7 @@ type settleAttemptArgs struct {
}
type failAttemptArgs struct {
reason *channeldb.HTLCFailInfo
reason *paymentsdb.HTLCFailInfo
}
type failPaymentArgs struct {
@@ -269,7 +269,7 @@ type failPaymentArgs struct {
type testPayment struct {
info channeldb.PaymentCreationInfo
attempts []channeldb.HTLCAttempt
attempts []paymentsdb.HTLCAttempt
}
type mockControlTowerOld struct {
@@ -355,7 +355,7 @@ func (m *mockControlTowerOld) DeleteFailedAttempts(phash lntypes.Hash) error {
}
func (m *mockControlTowerOld) RegisterAttempt(phash lntypes.Hash,
a *channeldb.HTLCAttemptInfo) error {
a *paymentsdb.HTLCAttemptInfo) error {
if m.registerAttempt != nil {
m.registerAttempt <- registerAttemptArgs{a}
@@ -400,7 +400,7 @@ func (m *mockControlTowerOld) RegisterAttempt(phash lntypes.Hash,
}
// Add attempt to payment.
p.attempts = append(p.attempts, channeldb.HTLCAttempt{
p.attempts = append(p.attempts, paymentsdb.HTLCAttempt{
HTLCAttemptInfo: *a,
})
m.payments[phash] = p
@@ -409,8 +409,8 @@ func (m *mockControlTowerOld) RegisterAttempt(phash lntypes.Hash,
}
func (m *mockControlTowerOld) SettleAttempt(phash lntypes.Hash,
pid uint64, settleInfo *channeldb.HTLCSettleInfo) (
*channeldb.HTLCAttempt, error) {
pid uint64, settleInfo *paymentsdb.HTLCSettleInfo) (
*paymentsdb.HTLCAttempt, error) {
if m.settleAttempt != nil {
m.settleAttempt <- settleAttemptArgs{settleInfo.Preimage}
@@ -442,7 +442,7 @@ func (m *mockControlTowerOld) SettleAttempt(phash lntypes.Hash,
// Mark the payment successful on first settled attempt.
m.successful[phash] = struct{}{}
return &channeldb.HTLCAttempt{
return &paymentsdb.HTLCAttempt{
Settle: settleInfo,
}, nil
}
@@ -451,7 +451,7 @@ func (m *mockControlTowerOld) SettleAttempt(phash lntypes.Hash,
}
func (m *mockControlTowerOld) FailAttempt(phash lntypes.Hash, pid uint64,
failInfo *channeldb.HTLCFailInfo) (*channeldb.HTLCAttempt, error) {
failInfo *paymentsdb.HTLCFailInfo) (*paymentsdb.HTLCAttempt, error) {
if m.failAttempt != nil {
m.failAttempt <- failAttemptArgs{failInfo}
@@ -480,7 +480,7 @@ func (m *mockControlTowerOld) FailAttempt(phash lntypes.Hash, pid uint64,
}
p.attempts[i].Failure = failInfo
return &channeldb.HTLCAttempt{
return &paymentsdb.HTLCAttempt{
Failure: failInfo,
}, nil
}
@@ -518,14 +518,14 @@ func (m *mockControlTowerOld) FetchPayment(phash lntypes.Hash) (
}
func (m *mockControlTowerOld) fetchPayment(phash lntypes.Hash) (
*channeldb.MPPayment, error) {
*paymentsdb.MPPayment, error) {
p, ok := m.payments[phash]
if !ok {
return nil, paymentsdb.ErrPaymentNotInitiated
}
mp := &channeldb.MPPayment{
mp := &paymentsdb.MPPayment{
Info: &p.info,
}
@@ -545,7 +545,7 @@ func (m *mockControlTowerOld) fetchPayment(phash lntypes.Hash) (
}
func (m *mockControlTowerOld) FetchInFlightPayments() (
[]*channeldb.MPPayment, error) {
[]*paymentsdb.MPPayment, error) {
if m.fetchInFlight != nil {
m.fetchInFlight <- struct{}{}
@@ -555,7 +555,7 @@ func (m *mockControlTowerOld) FetchInFlightPayments() (
defer m.Unlock()
// In flight are all payments not successful or failed.
var fl []*channeldb.MPPayment
var fl []*paymentsdb.MPPayment
for hash := range m.payments {
if _, ok := m.successful[hash]; ok {
continue
@@ -745,15 +745,15 @@ func (m *mockControlTower) DeleteFailedAttempts(phash lntypes.Hash) error {
}
func (m *mockControlTower) RegisterAttempt(phash lntypes.Hash,
a *channeldb.HTLCAttemptInfo) error {
a *paymentsdb.HTLCAttemptInfo) error {
args := m.Called(phash, a)
return args.Error(0)
}
func (m *mockControlTower) SettleAttempt(phash lntypes.Hash,
pid uint64, settleInfo *channeldb.HTLCSettleInfo) (
*channeldb.HTLCAttempt, error) {
pid uint64, settleInfo *paymentsdb.HTLCSettleInfo) (
*paymentsdb.HTLCAttempt, error) {
args := m.Called(phash, pid, settleInfo)
@@ -762,11 +762,11 @@ func (m *mockControlTower) SettleAttempt(phash lntypes.Hash,
return nil, args.Error(1)
}
return attempt.(*channeldb.HTLCAttempt), args.Error(1)
return attempt.(*paymentsdb.HTLCAttempt), args.Error(1)
}
func (m *mockControlTower) FailAttempt(phash lntypes.Hash, pid uint64,
failInfo *channeldb.HTLCFailInfo) (*channeldb.HTLCAttempt, error) {
failInfo *paymentsdb.HTLCFailInfo) (*paymentsdb.HTLCAttempt, error) {
args := m.Called(phash, pid, failInfo)
@@ -775,7 +775,7 @@ func (m *mockControlTower) FailAttempt(phash lntypes.Hash, pid uint64,
return nil, args.Error(1)
}
return args.Get(0).(*channeldb.HTLCAttempt), args.Error(1)
return attempt.(*paymentsdb.HTLCAttempt), args.Error(1)
}
func (m *mockControlTower) FailPayment(phash lntypes.Hash,
@@ -800,10 +800,10 @@ func (m *mockControlTower) FetchPayment(phash lntypes.Hash) (
}
func (m *mockControlTower) FetchInFlightPayments() (
[]*channeldb.MPPayment, error) {
[]*paymentsdb.MPPayment, error) {
args := m.Called()
return args.Get(0).([]*channeldb.MPPayment), args.Error(1)
return args.Get(0).([]*paymentsdb.MPPayment), args.Error(1)
}
func (m *mockControlTower) SubscribePayment(paymentHash lntypes.Hash) (
@@ -826,14 +826,14 @@ type mockMPPayment struct {
var _ DBMPPayment = (*mockMPPayment)(nil)
func (m *mockMPPayment) GetState() *channeldb.MPPaymentState {
func (m *mockMPPayment) GetState() *paymentsdb.MPPaymentState {
args := m.Called()
return args.Get(0).(*channeldb.MPPaymentState)
return args.Get(0).(*paymentsdb.MPPaymentState)
}
func (m *mockMPPayment) GetStatus() channeldb.PaymentStatus {
func (m *mockMPPayment) GetStatus() paymentsdb.PaymentStatus {
args := m.Called()
return args.Get(0).(channeldb.PaymentStatus)
return args.Get(0).(paymentsdb.PaymentStatus)
}
func (m *mockMPPayment) Terminated() bool {
@@ -847,14 +847,14 @@ func (m *mockMPPayment) NeedWaitAttempts() (bool, error) {
return args.Bool(0), args.Error(1)
}
func (m *mockMPPayment) GetHTLCs() []channeldb.HTLCAttempt {
func (m *mockMPPayment) GetHTLCs() []paymentsdb.HTLCAttempt {
args := m.Called()
return args.Get(0).([]channeldb.HTLCAttempt)
return args.Get(0).([]paymentsdb.HTLCAttempt)
}
func (m *mockMPPayment) InFlightHTLCs() []channeldb.HTLCAttempt {
func (m *mockMPPayment) InFlightHTLCs() []paymentsdb.HTLCAttempt {
args := m.Called()
return args.Get(0).([]channeldb.HTLCAttempt)
return args.Get(0).([]paymentsdb.HTLCAttempt)
}
func (m *mockMPPayment) AllowMoreAttempts() (bool, error) {
@@ -862,19 +862,19 @@ func (m *mockMPPayment) AllowMoreAttempts() (bool, error) {
return args.Bool(0), args.Error(1)
}
func (m *mockMPPayment) TerminalInfo() (*channeldb.HTLCAttempt,
func (m *mockMPPayment) TerminalInfo() (*paymentsdb.HTLCAttempt,
*channeldb.FailureReason) {
args := m.Called()
var (
settleInfo *channeldb.HTLCAttempt
settleInfo *paymentsdb.HTLCAttempt
failureInfo *channeldb.FailureReason
)
settle := args.Get(0)
if settle != nil {
settleInfo = settle.(*channeldb.HTLCAttempt)
settleInfo = settle.(*paymentsdb.HTLCAttempt)
}
reason := args.Get(1)

View File

@@ -16,6 +16,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"
"github.com/lightningnetwork/lnd/routing/shards"
"github.com/lightningnetwork/lnd/tlv"
@@ -29,7 +30,7 @@ var ErrPaymentLifecycleExiting = errors.New("payment lifecycle exiting")
// HTLC.
type switchResult struct {
// attempt is the HTLC sent to the switch.
attempt *channeldb.HTLCAttempt
attempt *paymentsdb.HTLCAttempt
// result is sent from the switch which contains either a preimage if
// ths HTLC is settled or an error if it's failed.
@@ -59,7 +60,7 @@ type paymentLifecycle struct {
// an HTLC attempt, which is always mounted to `p.collectResultAsync`
// except in unit test, where we use a much simpler resultCollector to
// decouple the test flow for the payment lifecycle.
resultCollector func(attempt *channeldb.HTLCAttempt)
resultCollector func(attempt *paymentsdb.HTLCAttempt)
}
// newPaymentLifecycle initiates a new payment lifecycle and returns it.
@@ -386,7 +387,7 @@ func (p *paymentLifecycle) checkContext(ctx context.Context) error {
// requestRoute is responsible for finding a route to be used to create an HTLC
// attempt.
func (p *paymentLifecycle) requestRoute(
ps *channeldb.MPPaymentState) (*route.Route, error) {
ps *paymentsdb.MPPaymentState) (*route.Route, error) {
remainingFees := p.calcFeeBudget(ps.FeesPaid)
@@ -455,14 +456,14 @@ type attemptResult struct {
err error
// attempt is the attempt structure as recorded in the database.
attempt *channeldb.HTLCAttempt
attempt *paymentsdb.HTLCAttempt
}
// collectResultAsync launches a goroutine that will wait for the result of the
// given HTLC attempt to be available then save its result in a map. Once
// received, it will send the result returned from the switch to channel
// `resultCollected`.
func (p *paymentLifecycle) collectResultAsync(attempt *channeldb.HTLCAttempt) {
func (p *paymentLifecycle) collectResultAsync(attempt *paymentsdb.HTLCAttempt) {
log.Debugf("Collecting result for attempt %v in payment %v",
attempt.AttemptID, p.identifier)
@@ -504,7 +505,7 @@ func (p *paymentLifecycle) collectResultAsync(attempt *channeldb.HTLCAttempt) {
// collectResult waits for the result of the given HTLC attempt to be sent by
// the switch and returns it.
func (p *paymentLifecycle) collectResult(
attempt *channeldb.HTLCAttempt) (*htlcswitch.PaymentResult, error) {
attempt *paymentsdb.HTLCAttempt) (*htlcswitch.PaymentResult, error) {
log.Tracef("Collecting result for attempt %v",
lnutils.SpewLogClosure(attempt))
@@ -581,7 +582,7 @@ func (p *paymentLifecycle) collectResult(
// by using the route info provided. The `remainingAmt` is used to decide
// whether this is the last attempt.
func (p *paymentLifecycle) registerAttempt(rt *route.Route,
remainingAmt lnwire.MilliSatoshi) (*channeldb.HTLCAttempt, error) {
remainingAmt lnwire.MilliSatoshi) (*paymentsdb.HTLCAttempt, error) {
// If this route will consume the last remaining amount to send
// to the receiver, this will be our last shard (for now).
@@ -608,7 +609,7 @@ func (p *paymentLifecycle) registerAttempt(rt *route.Route,
// createNewPaymentAttempt creates a new payment attempt from the given route.
func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route,
lastShard bool) (*channeldb.HTLCAttempt, error) {
lastShard bool) (*paymentsdb.HTLCAttempt, error) {
// Generate a new key to be used for this attempt.
sessionKey, err := generateNewSessionKey()
@@ -648,7 +649,7 @@ func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route,
// We now have all the information needed to populate the current
// attempt information.
return channeldb.NewHtlcAttempt(
return paymentsdb.NewHtlcAttempt(
attemptID, sessionKey, *rt, p.router.cfg.Clock.Now(), &hash,
)
}
@@ -657,7 +658,7 @@ func (p *paymentLifecycle) createNewPaymentAttempt(rt *route.Route,
// the payment. If this attempt fails, then we'll continue on to the next
// available route.
func (p *paymentLifecycle) sendAttempt(
attempt *channeldb.HTLCAttempt) (*attemptResult, error) {
attempt *paymentsdb.HTLCAttempt) (*attemptResult, error) {
log.Debugf("Sending HTLC attempt(id=%v, total_amt=%v, first_hop_amt=%d"+
") for payment %v", attempt.AttemptID,
@@ -823,7 +824,7 @@ func (p *paymentLifecycle) failPaymentAndAttempt(
// the error type, the error is either the final outcome of the payment or we
// need to continue with an alternative route. A final outcome is indicated by
// a non-nil reason value.
func (p *paymentLifecycle) handleSwitchErr(attempt *channeldb.HTLCAttempt,
func (p *paymentLifecycle) handleSwitchErr(attempt *paymentsdb.HTLCAttempt,
sendErr error) (*attemptResult, error) {
internalErrorReason := channeldb.FailureReasonError
@@ -1030,34 +1031,34 @@ func (p *paymentLifecycle) failAttempt(attemptID uint64,
// marshallError marshall an error as received from the switch to a structure
// that is suitable for database storage.
func marshallError(sendError error, time time.Time) *channeldb.HTLCFailInfo {
response := &channeldb.HTLCFailInfo{
func marshallError(sendError error, time time.Time) *paymentsdb.HTLCFailInfo {
response := &paymentsdb.HTLCFailInfo{
FailTime: time,
}
switch {
case errors.Is(sendError, htlcswitch.ErrPaymentIDNotFound):
response.Reason = channeldb.HTLCFailInternal
response.Reason = paymentsdb.HTLCFailInternal
return response
case errors.Is(sendError, htlcswitch.ErrUnreadableFailureMessage):
response.Reason = channeldb.HTLCFailUnreadable
response.Reason = paymentsdb.HTLCFailUnreadable
return response
}
var rtErr htlcswitch.ClearTextError
ok := errors.As(sendError, &rtErr)
if !ok {
response.Reason = channeldb.HTLCFailInternal
response.Reason = paymentsdb.HTLCFailInternal
return response
}
message := rtErr.WireMessage()
if message != nil {
response.Reason = channeldb.HTLCFailMessage
response.Reason = paymentsdb.HTLCFailMessage
response.Message = message
} else {
response.Reason = channeldb.HTLCFailUnknown
response.Reason = paymentsdb.HTLCFailUnknown
}
// If the ClearTextError received is a ForwardingError, the error
@@ -1082,7 +1083,7 @@ func marshallError(sendError error, time time.Time) *channeldb.HTLCFailInfo {
// enabled, the `Hash` field in their HTLC attempts is nil. In that case, we use
// the payment hash as the `attempt.Hash` as they are identical.
func (p *paymentLifecycle) patchLegacyPaymentHash(
a channeldb.HTLCAttempt) channeldb.HTLCAttempt {
a paymentsdb.HTLCAttempt) paymentsdb.HTLCAttempt {
// Exit early if this is not a legacy attempt.
if a.Hash != nil {
@@ -1134,7 +1135,7 @@ func (p *paymentLifecycle) reloadInflightAttempts() (DBMPPayment, error) {
// reloadPayment returns the latest payment found in the db (control tower).
func (p *paymentLifecycle) reloadPayment() (DBMPPayment,
*channeldb.MPPaymentState, error) {
*paymentsdb.MPPaymentState, error) {
// Read the db to get the latest state of the payment.
payment, err := p.router.cfg.Control.FetchPayment(p.identifier)
@@ -1154,7 +1155,7 @@ func (p *paymentLifecycle) reloadPayment() (DBMPPayment,
// handleAttemptResult processes the result of an HTLC attempt returned from
// the htlcswitch.
func (p *paymentLifecycle) handleAttemptResult(attempt *channeldb.HTLCAttempt,
func (p *paymentLifecycle) handleAttemptResult(attempt *paymentsdb.HTLCAttempt,
result *htlcswitch.PaymentResult) (*attemptResult, error) {
// If the result has an error, we need to further process it by failing
@@ -1179,7 +1180,7 @@ func (p *paymentLifecycle) handleAttemptResult(attempt *channeldb.HTLCAttempt,
// move the shard to the settled state.
htlcAttempt, err := p.router.cfg.Control.SettleAttempt(
p.identifier, attempt.AttemptID,
&channeldb.HTLCSettleInfo{
&paymentsdb.HTLCSettleInfo{
Preimage: result.Preimage,
SettleTime: p.router.cfg.Clock.Now(),
},
@@ -1204,7 +1205,7 @@ func (p *paymentLifecycle) handleAttemptResult(attempt *channeldb.HTLCAttempt,
// tower. An attemptResult is returned, indicating the final outcome of this
// HTLC attempt.
func (p *paymentLifecycle) collectAndHandleResult(
attempt *channeldb.HTLCAttempt) (*attemptResult, error) {
attempt *paymentsdb.HTLCAttempt) (*attemptResult, error) {
result, err := p.collectResult(attempt)
if err != nil {

View File

@@ -15,6 +15,7 @@ import (
"github.com/lightningnetwork/lnd/lntest/wait"
"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/stretchr/testify/mock"
@@ -116,7 +117,7 @@ func newTestPaymentLifecycle(t *testing.T) (*paymentLifecycle, *mockers) {
// Overwrite the collectResultAsync to focus on testing the payment
// lifecycle within the goroutine.
resultCollector := func(attempt *channeldb.HTLCAttempt) {
resultCollector := func(attempt *paymentsdb.HTLCAttempt) {
mockers.collectResultsCount++
}
p.resultCollector = resultCollector
@@ -147,7 +148,7 @@ func setupTestPaymentLifecycle(t *testing.T) (*paymentLifecycle, *mockers) {
m.payment, nil,
).Once()
htlcs := []channeldb.HTLCAttempt{}
htlcs := []paymentsdb.HTLCAttempt{}
m.payment.On("InFlightHTLCs").Return(htlcs).Once()
return p, m
@@ -258,11 +259,11 @@ func createDummyRoute(t *testing.T, amt lnwire.MilliSatoshi) *route.Route {
}
func makeSettledAttempt(t *testing.T, total int,
preimage lntypes.Preimage) *channeldb.HTLCAttempt {
preimage lntypes.Preimage) *paymentsdb.HTLCAttempt {
a := &channeldb.HTLCAttempt{
a := &paymentsdb.HTLCAttempt{
HTLCAttemptInfo: makeAttemptInfo(t, total),
Settle: &channeldb.HTLCSettleInfo{Preimage: preimage},
Settle: &paymentsdb.HTLCSettleInfo{Preimage: preimage},
}
hash := preimage.Hash()
@@ -271,18 +272,18 @@ func makeSettledAttempt(t *testing.T, total int,
return a
}
func makeFailedAttempt(t *testing.T, total int) *channeldb.HTLCAttempt {
return &channeldb.HTLCAttempt{
func makeFailedAttempt(t *testing.T, total int) *paymentsdb.HTLCAttempt {
return &paymentsdb.HTLCAttempt{
HTLCAttemptInfo: makeAttemptInfo(t, total),
Failure: &channeldb.HTLCFailInfo{
Reason: channeldb.HTLCFailInternal,
Failure: &paymentsdb.HTLCFailInfo{
Reason: paymentsdb.HTLCFailInternal,
},
}
}
func makeAttemptInfo(t *testing.T, amt int) channeldb.HTLCAttemptInfo {
func makeAttemptInfo(t *testing.T, amt int) paymentsdb.HTLCAttemptInfo {
rt := createDummyRoute(t, lnwire.MilliSatoshi(amt))
return channeldb.HTLCAttemptInfo{
return paymentsdb.HTLCAttemptInfo{
Route: *rt,
Hash: &lntypes.Hash{1, 2, 3},
}
@@ -378,7 +379,7 @@ func TestRequestRouteSucceed(t *testing.T) {
p.paySession = paySession
// Create a dummy payment state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
NumAttemptsInFlight: 1,
RemainingAmt: 1,
FeesPaid: 100,
@@ -415,7 +416,7 @@ func TestRequestRouteHandleCriticalErr(t *testing.T) {
p.paySession = paySession
// Create a dummy payment state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
NumAttemptsInFlight: 1,
RemainingAmt: 1,
FeesPaid: 100,
@@ -449,7 +450,7 @@ func TestRequestRouteHandleNoRouteErr(t *testing.T) {
p, m := newTestPaymentLifecycle(t)
// Create a dummy payment state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
NumAttemptsInFlight: 1,
RemainingAmt: 1,
FeesPaid: 100,
@@ -498,7 +499,7 @@ func TestRequestRouteFailPaymentError(t *testing.T) {
p.paySession = paySession
// Create a dummy payment state with zero inflight attempts.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
NumAttemptsInFlight: 0,
RemainingAmt: 1,
FeesPaid: 100,
@@ -819,14 +820,14 @@ func TestResumePaymentFailOnTimeout(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
// NOTE: GetStatus is only used to populate the logs which is not
// critical, so we loosen the checks on how many times it's been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 3. make the timeout happens instantly and sleep one millisecond to
// make sure it timed out.
@@ -875,7 +876,7 @@ func TestResumePaymentFailOnTimeoutErr(t *testing.T) {
// NOTE: GetStatus is only used to populate the logs which is
// not critical so we loosen the checks on how many times it's
// been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// Quit the router to return an error.
close(p.router.quit)
@@ -910,14 +911,14 @@ func TestResumePaymentFailContextCancel(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
// NOTE: GetStatus is only used to populate the logs which is not
// critical, so we loosen the checks on how many times it's been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 3. Cancel the context and skip the FailPayment error to trigger the
// context cancellation of the payment.
@@ -963,7 +964,7 @@ func TestResumePaymentFailOnStepErr(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
@@ -971,7 +972,7 @@ func TestResumePaymentFailOnStepErr(t *testing.T) {
// NOTE: GetStatus is only used to populate the logs which is
// not critical so we loosen the checks on how many times it's
// been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 3. decideNextStep now returns an error.
m.payment.On("AllowMoreAttempts").Return(false, errDummy).Once()
@@ -1001,7 +1002,7 @@ func TestResumePaymentFailOnRequestRouteErr(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
@@ -1009,7 +1010,7 @@ func TestResumePaymentFailOnRequestRouteErr(t *testing.T) {
// NOTE: GetStatus is only used to populate the logs which is
// not critical so we loosen the checks on how many times it's
// been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 3. decideNextStep now returns stepProceed.
m.payment.On("AllowMoreAttempts").Return(true, nil).Once()
@@ -1047,7 +1048,7 @@ func TestResumePaymentFailOnRegisterAttemptErr(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
@@ -1055,7 +1056,7 @@ func TestResumePaymentFailOnRegisterAttemptErr(t *testing.T) {
// NOTE: GetStatus is only used to populate the logs which is
// not critical so we loosen the checks on how many times it's
// been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 3. decideNextStep now returns stepProceed.
m.payment.On("AllowMoreAttempts").Return(true, nil).Once()
@@ -1107,7 +1108,7 @@ func TestResumePaymentFailOnSendAttemptErr(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
@@ -1115,7 +1116,7 @@ func TestResumePaymentFailOnSendAttemptErr(t *testing.T) {
// NOTE: GetStatus is only used to populate the logs which is
// not critical so we loosen the checks on how many times it's
// been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 3. decideNextStep now returns stepProceed.
m.payment.On("AllowMoreAttempts").Return(true, nil).Once()
@@ -1199,7 +1200,7 @@ func TestResumePaymentSuccess(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 1.2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
@@ -1207,7 +1208,7 @@ func TestResumePaymentSuccess(t *testing.T) {
// NOTE: GetStatus is only used to populate the logs which is
// not critical so we loosen the checks on how many times it's
// been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 1.3. decideNextStep now returns stepProceed.
m.payment.On("AllowMoreAttempts").Return(true, nil).Once()
@@ -1300,7 +1301,7 @@ func TestResumePaymentSuccessWithTwoAttempts(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 1.2. calls `GetState` and return the state.
ps := &channeldb.MPPaymentState{
ps := &paymentsdb.MPPaymentState{
RemainingAmt: paymentAmt,
}
m.payment.On("GetState").Return(ps).Once()
@@ -1308,7 +1309,7 @@ func TestResumePaymentSuccessWithTwoAttempts(t *testing.T) {
// NOTE: GetStatus is only used to populate the logs which is
// not critical so we loosen the checks on how many times it's
// been called.
m.payment.On("GetStatus").Return(channeldb.StatusInFlight)
m.payment.On("GetStatus").Return(paymentsdb.StatusInFlight)
// 1.3. decideNextStep now returns stepProceed.
m.payment.On("AllowMoreAttempts").Return(true, nil).Once()
@@ -1833,7 +1834,7 @@ func TestReloadInflightAttemptsLegacy(t *testing.T) {
m.control.On("FetchPayment", p.identifier).Return(m.payment, nil).Once()
// 2. calls `InFlightHTLCs` and return the attempt.
attempts := []channeldb.HTLCAttempt{*attempt}
attempts := []paymentsdb.HTLCAttempt{*attempt}
m.payment.On("InFlightHTLCs").Return(attempts).Once()
// 3. Mock the htlcswitch to return a the result chan.

View File

@@ -1038,7 +1038,7 @@ func (r *ChannelRouter) PreparePayment(payment *LightningPayment) (
// SendToRoute sends a payment using the provided route and fails the payment
// when an error is returned from the attempt.
func (r *ChannelRouter) SendToRoute(htlcHash lntypes.Hash, rt *route.Route,
firstHopCustomRecords lnwire.CustomRecords) (*channeldb.HTLCAttempt,
firstHopCustomRecords lnwire.CustomRecords) (*paymentsdb.HTLCAttempt,
error) {
return r.sendToRoute(htlcHash, rt, false, firstHopCustomRecords)
@@ -1048,7 +1048,7 @@ func (r *ChannelRouter) SendToRoute(htlcHash lntypes.Hash, rt *route.Route,
// the payment ONLY when a terminal error is returned from the attempt.
func (r *ChannelRouter) SendToRouteSkipTempErr(htlcHash lntypes.Hash,
rt *route.Route,
firstHopCustomRecords lnwire.CustomRecords) (*channeldb.HTLCAttempt,
firstHopCustomRecords lnwire.CustomRecords) (*paymentsdb.HTLCAttempt,
error) {
return r.sendToRoute(htlcHash, rt, true, firstHopCustomRecords)
@@ -1062,7 +1062,7 @@ func (r *ChannelRouter) SendToRouteSkipTempErr(htlcHash lntypes.Hash,
// the payment won't be failed unless a terminal error has occurred.
func (r *ChannelRouter) sendToRoute(htlcHash lntypes.Hash, rt *route.Route,
skipTempErr bool,
firstHopCustomRecords lnwire.CustomRecords) (*channeldb.HTLCAttempt,
firstHopCustomRecords lnwire.CustomRecords) (*paymentsdb.HTLCAttempt,
error) {
// Helper function to fail a payment. It makes sure the payment is only
@@ -1448,7 +1448,7 @@ func (r *ChannelRouter) resumePayments() error {
}
// launchPayment is a helper closure that handles resuming the payment.
launchPayment := func(payment *channeldb.MPPayment) {
launchPayment := func(payment *paymentsdb.MPPayment) {
defer r.wg.Done()
// Get the hashes used for the outstanding HTLCs.
@@ -1523,7 +1523,7 @@ func (r *ChannelRouter) resumePayments() error {
// attempt to NOT be saved, resulting a payment being stuck forever. More info:
// - https://github.com/lightningnetwork/lnd/issues/8146
// - https://github.com/lightningnetwork/lnd/pull/8174
func (r *ChannelRouter) failStaleAttempt(a channeldb.HTLCAttempt,
func (r *ChannelRouter) failStaleAttempt(a paymentsdb.HTLCAttempt,
payHash lntypes.Hash) {
// We can only fail inflight HTLCs so we skip the settled/failed ones.
@@ -1605,8 +1605,8 @@ func (r *ChannelRouter) failStaleAttempt(a channeldb.HTLCAttempt,
// Fail the attempt in db. If there's an error, there's nothing we can
// do here but logging it.
failInfo := &channeldb.HTLCFailInfo{
Reason: channeldb.HTLCFailUnknown,
failInfo := &paymentsdb.HTLCFailInfo{
Reason: paymentsdb.HTLCFailUnknown,
FailTime: r.cfg.Clock.Now(),
}
_, err = r.cfg.Control.FailAttempt(payHash, a.AttemptID, failInfo)