channeldb: rename PaymentControl struct

In the following commits we will gradually unify the current
payment db operations into an interface to later down the road
support both backends (sql+kv).
This commit is contained in:
ziggie
2025-08-01 17:01:19 +02:00
parent 252ebdea5b
commit 2d07d44d1a
6 changed files with 74 additions and 74 deletions

View File

@@ -130,17 +130,17 @@ var (
"does not exist")
)
// PaymentControl implements persistence for payments and payment attempts.
type PaymentControl struct {
// KVPaymentsDB implements persistence for payments and payment attempts.
type KVPaymentsDB struct {
paymentSeqMx sync.Mutex
currPaymentSeq uint64
storedPaymentSeq uint64
db *DB
}
// NewPaymentControl creates a new instance of the PaymentControl.
func NewPaymentControl(db *DB) *PaymentControl {
return &PaymentControl{
// NewKVPaymentsDB creates a new instance of the KVPaymentsDB.
func NewKVPaymentsDB(db *DB) *KVPaymentsDB {
return &KVPaymentsDB{
db: db,
}
}
@@ -149,7 +149,7 @@ func NewPaymentControl(db *DB) *PaymentControl {
// making sure it does not already exist as an in-flight payment. When this
// method returns successfully, the payment is guaranteed to be in the InFlight
// state.
func (p *PaymentControl) InitPayment(paymentHash lntypes.Hash,
func (p *KVPaymentsDB) InitPayment(paymentHash lntypes.Hash,
info *PaymentCreationInfo) error {
// Obtain a new sequence number for this payment. This is used
@@ -252,8 +252,8 @@ func (p *PaymentControl) InitPayment(paymentHash lntypes.Hash,
}
// DeleteFailedAttempts deletes all failed htlcs for a payment if configured
// by the PaymentControl db.
func (p *PaymentControl) DeleteFailedAttempts(hash lntypes.Hash) error {
// by the KVPaymentsDB db.
func (p *KVPaymentsDB) DeleteFailedAttempts(hash lntypes.Hash) error {
if !p.db.keepFailedPaymentAttempts {
const failedHtlcsOnly = true
err := p.db.DeletePayment(hash, failedHtlcsOnly)
@@ -318,7 +318,7 @@ func deserializePaymentIndex(r io.Reader) (lntypes.Hash, error) {
// RegisterAttempt atomically records the provided HTLCAttemptInfo to the
// DB.
func (p *PaymentControl) RegisterAttempt(paymentHash lntypes.Hash,
func (p *KVPaymentsDB) RegisterAttempt(paymentHash lntypes.Hash,
attempt *HTLCAttemptInfo) (*MPPayment, error) {
// Serialize the information before opening the db transaction.
@@ -467,7 +467,7 @@ func (p *PaymentControl) RegisterAttempt(paymentHash lntypes.Hash,
// After invoking this method, InitPayment should always return an 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.
func (p *PaymentControl) SettleAttempt(hash lntypes.Hash,
func (p *KVPaymentsDB) SettleAttempt(hash lntypes.Hash,
attemptID uint64, settleInfo *HTLCSettleInfo) (*MPPayment, error) {
var b bytes.Buffer
@@ -480,7 +480,7 @@ func (p *PaymentControl) SettleAttempt(hash lntypes.Hash,
}
// FailAttempt marks the given payment attempt failed.
func (p *PaymentControl) FailAttempt(hash lntypes.Hash,
func (p *KVPaymentsDB) FailAttempt(hash lntypes.Hash,
attemptID uint64, failInfo *HTLCFailInfo) (*MPPayment, error) {
var b bytes.Buffer
@@ -493,7 +493,7 @@ func (p *PaymentControl) FailAttempt(hash lntypes.Hash,
}
// updateHtlcKey updates a database key for the specified htlc.
func (p *PaymentControl) updateHtlcKey(paymentHash lntypes.Hash,
func (p *KVPaymentsDB) updateHtlcKey(paymentHash lntypes.Hash,
attemptID uint64, key, value []byte) (*MPPayment, error) {
aid := make([]byte, 8)
@@ -561,7 +561,7 @@ func (p *PaymentControl) updateHtlcKey(paymentHash lntypes.Hash,
// payment failed. After invoking this method, InitPayment should return nil on
// its next call for this payment hash, allowing the switch to make a
// subsequent payment.
func (p *PaymentControl) Fail(paymentHash lntypes.Hash,
func (p *KVPaymentsDB) Fail(paymentHash lntypes.Hash,
reason FailureReason) (*MPPayment, error) {
var (
@@ -585,7 +585,7 @@ func (p *PaymentControl) Fail(paymentHash lntypes.Hash,
// We mark the payment as failed as long as it is known. This
// lets the last attempt to fail with a terminal write its
// failure to the PaymentControl without synchronizing with
// failure to the KVPaymentsDB without synchronizing with
// other attempts.
_, err = fetchPaymentStatus(bucket)
if errors.Is(err, ErrPaymentNotInitiated) {
@@ -618,7 +618,7 @@ func (p *PaymentControl) Fail(paymentHash lntypes.Hash,
}
// FetchPayment returns information about a payment from the database.
func (p *PaymentControl) FetchPayment(paymentHash lntypes.Hash) (
func (p *KVPaymentsDB) FetchPayment(paymentHash lntypes.Hash) (
*MPPayment, error) {
var payment *MPPayment
@@ -714,7 +714,7 @@ func fetchPaymentBucketUpdate(tx kvdb.RwTx, paymentHash lntypes.Hash) (
// nextPaymentSequence returns the next sequence number to store for a new
// payment.
func (p *PaymentControl) nextPaymentSequence() ([]byte, error) {
func (p *KVPaymentsDB) nextPaymentSequence() ([]byte, error) {
p.paymentSeqMx.Lock()
defer p.paymentSeqMx.Unlock()
@@ -774,7 +774,7 @@ func fetchPaymentStatus(bucket kvdb.RBucket) (PaymentStatus, error) {
}
// FetchInFlightPayments returns all payments with status InFlight.
func (p *PaymentControl) FetchInFlightPayments() ([]*MPPayment, error) {
func (p *KVPaymentsDB) FetchInFlightPayments() ([]*MPPayment, error) {
var (
inFlights []*MPPayment
start = time.Now()

View File

@@ -54,16 +54,16 @@ func genInfo(t *testing.T) (*PaymentCreationInfo, *HTLCAttemptInfo,
}, &attempt.HTLCAttemptInfo, preimage, nil
}
// TestPaymentControlSwitchFail checks that payment status returns to Failed
// TestKVPaymentsDBSwitchFail checks that payment status returns to Failed
// status after failing, and that InitPayment allows another HTLC for the
// same payment hash.
func TestPaymentControlSwitchFail(t *testing.T) {
func TestKVPaymentsDBSwitchFail(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to init db")
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
info, attempt, preimg, err := genInfo(t)
require.NoError(t, err, "unable to generate htlc message")
@@ -191,15 +191,15 @@ func TestPaymentControlSwitchFail(t *testing.T) {
}
}
// TestPaymentControlSwitchDoubleSend checks the ability of payment control to
// TestKVPaymentsDBSwitchDoubleSend checks the ability of payment control to
// prevent double sending of htlc message, when message is in StatusInFlight.
func TestPaymentControlSwitchDoubleSend(t *testing.T) {
func TestKVPaymentsDBSwitchDoubleSend(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to init db")
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
info, attempt, preimg, err := genInfo(t)
require.NoError(t, err, "unable to generate htlc message")
@@ -261,15 +261,15 @@ func TestPaymentControlSwitchDoubleSend(t *testing.T) {
}
}
// TestPaymentControlSuccessesWithoutInFlight checks that the payment
// TestKVPaymentsDBSuccessesWithoutInFlight checks that the payment
// control will disallow calls to Success when no payment is in flight.
func TestPaymentControlSuccessesWithoutInFlight(t *testing.T) {
func TestKVPaymentsDBSuccessesWithoutInFlight(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to init db")
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
info, _, preimg, err := genInfo(t)
require.NoError(t, err, "unable to generate htlc message")
@@ -286,15 +286,15 @@ func TestPaymentControlSuccessesWithoutInFlight(t *testing.T) {
}
}
// TestPaymentControlFailsWithoutInFlight checks that a strict payment
// TestKVPaymentsDBFailsWithoutInFlight checks that a strict payment
// control will disallow calls to Fail when no payment is in flight.
func TestPaymentControlFailsWithoutInFlight(t *testing.T) {
func TestKVPaymentsDBFailsWithoutInFlight(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to init db")
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
info, _, _, err := genInfo(t)
require.NoError(t, err, "unable to generate htlc message")
@@ -306,9 +306,9 @@ func TestPaymentControlFailsWithoutInFlight(t *testing.T) {
}
}
// TestPaymentControlDeleteNonInFlight checks that calling DeletePayments only
// TestKVPaymentsDBDeleteNonInFlight checks that calling DeletePayments only
// deletes payments from the database that are not in-flight.
func TestPaymentControlDeleteNonInFlight(t *testing.T) {
func TestKVPaymentsDBDeleteNonInFlight(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
@@ -319,7 +319,7 @@ func TestPaymentControlDeleteNonInFlight(t *testing.T) {
// start at 1, so 9999 is a safe bet for this test.
var duplicateSeqNr = 9999
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
payments := []struct {
failed bool
@@ -513,15 +513,15 @@ func TestPaymentControlDeleteNonInFlight(t *testing.T) {
require.Equal(t, 1, indexCount)
}
// TestPaymentControlDeletePayments tests that DeletePayments correctly deletes
// TestKVPaymentsDBDeletePayments tests that DeletePayments correctly deletes
// information about completed payments from the database.
func TestPaymentControlDeletePayments(t *testing.T) {
func TestKVPaymentsDBDeletePayments(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to init db")
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
// Register three payments:
// 1. A payment with two failed attempts.
@@ -574,15 +574,15 @@ func TestPaymentControlDeletePayments(t *testing.T) {
assertPayments(t, db, payments[2:])
}
// TestPaymentControlDeleteSinglePayment tests that DeletePayment correctly
// TestKVPaymentsDBDeleteSinglePayment tests that DeletePayment correctly
// deletes information about a completed payment from the database.
func TestPaymentControlDeleteSinglePayment(t *testing.T) {
func TestKVPaymentsDBDeleteSinglePayment(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to init db")
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
// Register four payments:
// All payments will have one failed HTLC attempt and one HTLC attempt
@@ -660,9 +660,9 @@ func TestPaymentControlDeleteSinglePayment(t *testing.T) {
assertPayments(t, db, payments[3:])
}
// TestPaymentControlMultiShard checks the ability of payment control to
// TestKVPaymentsDBMultiShard checks the ability of payment control to
// have multiple in-flight HTLCs for a single payment.
func TestPaymentControlMultiShard(t *testing.T) {
func TestKVPaymentsDBMultiShard(t *testing.T) {
t.Parallel()
// We will register three HTLC attempts, and always fail the second
@@ -687,7 +687,7 @@ func TestPaymentControlMultiShard(t *testing.T) {
t.Fatalf("unable to init db: %v", err)
}
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
info, attempt, preimg, err := genInfo(t)
if err != nil {
@@ -945,13 +945,13 @@ func TestPaymentControlMultiShard(t *testing.T) {
}
}
func TestPaymentControlMPPRecordValidation(t *testing.T) {
func TestKVPaymentsDBMPPRecordValidation(t *testing.T) {
t.Parallel()
db, err := MakeTestDB(t)
require.NoError(t, err, "unable to init db")
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
info, attempt, _, err := genInfo(t)
require.NoError(t, err, "unable to generate htlc message")
@@ -1044,7 +1044,7 @@ func testDeleteFailedAttempts(t *testing.T, keepFailedPaymentAttempts bool) {
require.NoError(t, err, "unable to init db")
db.keepFailedPaymentAttempts = keepFailedPaymentAttempts
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
// Register three payments:
// All payments will have one failed HTLC attempt and one HTLC attempt
@@ -1116,7 +1116,7 @@ func testDeleteFailedAttempts(t *testing.T, keepFailedPaymentAttempts bool) {
// assertPaymentStatus retrieves the status of the payment referred to by hash
// and compares it with the expected state.
func assertPaymentStatus(t *testing.T, p *PaymentControl,
func assertPaymentStatus(t *testing.T, p *KVPaymentsDB,
hash lntypes.Hash, expStatus PaymentStatus) {
t.Helper()
@@ -1143,7 +1143,7 @@ type htlcStatus struct {
// assertPaymentInfo retrieves the payment referred to by hash and verifies the
// expected values.
func assertPaymentInfo(t *testing.T, p *PaymentControl, hash lntypes.Hash,
func assertPaymentInfo(t *testing.T, p *KVPaymentsDB, hash lntypes.Hash,
c *PaymentCreationInfo, f *FailureReason, a *htlcStatus) {
t.Helper()
@@ -1210,7 +1210,7 @@ func assertPaymentInfo(t *testing.T, p *PaymentControl, hash lntypes.Hash,
// fetchPaymentIndexEntry gets the payment hash for the sequence number provided
// from our payment indexes bucket.
func fetchPaymentIndexEntry(_ *testing.T, p *PaymentControl,
func fetchPaymentIndexEntry(_ *testing.T, p *KVPaymentsDB,
sequenceNumber uint64) (*lntypes.Hash, error) {
var hash lntypes.Hash
@@ -1241,7 +1241,7 @@ func fetchPaymentIndexEntry(_ *testing.T, p *PaymentControl,
// assertPaymentIndex looks up the index for a payment in the db and checks
// that its payment hash matches the expected hash passed in.
func assertPaymentIndex(t *testing.T, p *PaymentControl,
func assertPaymentIndex(t *testing.T, p *KVPaymentsDB,
expectedHash lntypes.Hash) {
// Lookup the payment so that we have its sequence number and check
@@ -1256,7 +1256,7 @@ func assertPaymentIndex(t *testing.T, p *PaymentControl,
// assertNoIndex checks that an index for the sequence number provided does not
// exist.
func assertNoIndex(t *testing.T, p *PaymentControl, seqNr uint64) {
func assertNoIndex(t *testing.T, p *KVPaymentsDB, seqNr uint64) {
_, err := fetchPaymentIndexEntry(t, p, seqNr)
require.Equal(t, errNoSequenceNrIndex, err)
}
@@ -1272,7 +1272,7 @@ type payment struct {
// createTestPayments registers payments depending on the provided statuses in
// the payments slice. Each payment will receive one failed HTLC and another
// HTLC depending on the final status of the payment provided.
func createTestPayments(t *testing.T, p *PaymentControl, payments []*payment) {
func createTestPayments(t *testing.T, p *KVPaymentsDB, payments []*payment) {
attemptID := uint64(0)
for i := 0; i < len(payments); i++ {

View File

@@ -516,7 +516,7 @@ func TestQueryPayments(t *testing.T) {
// where we have duplicates in the nested duplicates
// bucket.
nonDuplicatePayments := 6
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
for i := 0; i < nonDuplicatePayments; i++ {
// Generate a test payment.
@@ -618,7 +618,7 @@ func TestFetchPaymentWithSequenceNumber(t *testing.T) {
db, err := MakeTestDB(t)
require.NoError(t, err)
pControl := NewPaymentControl(db)
pControl := NewKVPaymentsDB(db)
// Generate a test payment which does not have duplicates.
noDuplicates, _, _, err := genInfo(t)

View File

@@ -151,7 +151,7 @@ func (s *controlTowerSubscriberImpl) Updates() <-chan interface{} {
// controlTower is persistent implementation of ControlTower to restrict
// double payment sending.
type controlTower struct {
db *channeldb.PaymentControl
db *channeldb.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 +168,7 @@ type controlTower struct {
}
// NewControlTower creates a new instance of the controlTower.
func NewControlTower(db *channeldb.PaymentControl) ControlTower {
func NewControlTower(db *channeldb.KVPaymentsDB) ControlTower {
return &controlTower{
db: db,
subscribersAllPayments: make(

View File

@@ -49,7 +49,7 @@ func TestControlTowerSubscribeUnknown(t *testing.T) {
db := initDB(t, false)
pControl := NewControlTower(channeldb.NewPaymentControl(db))
pControl := NewControlTower(channeldb.NewKVPaymentsDB(db))
// Subscription should fail when the payment is not known.
_, err := pControl.SubscribePayment(lntypes.Hash{1})
@@ -63,7 +63,7 @@ func TestControlTowerSubscribeSuccess(t *testing.T) {
db := initDB(t, false)
pControl := NewControlTower(channeldb.NewPaymentControl(db))
pControl := NewControlTower(channeldb.NewKVPaymentsDB(db))
// Initiate a payment.
info, attempt, preimg, err := genInfo()
@@ -156,33 +156,33 @@ func TestControlTowerSubscribeSuccess(t *testing.T) {
}
}
// TestPaymentControlSubscribeFail tests that payment updates for a
// TestKVPaymentsDBSubscribeFail tests that payment updates for a
// failed payment are properly sent to subscribers.
func TestPaymentControlSubscribeFail(t *testing.T) {
func TestKVPaymentsDBSubscribeFail(t *testing.T) {
t.Parallel()
t.Run("register attempt, keep failed payments", func(t *testing.T) {
testPaymentControlSubscribeFail(t, true, true)
testKVPaymentsDBSubscribeFail(t, true, true)
})
t.Run("register attempt, delete failed payments", func(t *testing.T) {
testPaymentControlSubscribeFail(t, true, false)
testKVPaymentsDBSubscribeFail(t, true, false)
})
t.Run("no register attempt, keep failed payments", func(t *testing.T) {
testPaymentControlSubscribeFail(t, false, true)
testKVPaymentsDBSubscribeFail(t, false, true)
})
t.Run("no register attempt, delete failed payments", func(t *testing.T) {
testPaymentControlSubscribeFail(t, false, false)
testKVPaymentsDBSubscribeFail(t, false, false)
})
}
// TestPaymentControlSubscribeAllSuccess tests that multiple payments are
// TestKVPaymentsDBSubscribeAllSuccess tests that multiple payments are
// properly sent to subscribers of TrackPayments.
func TestPaymentControlSubscribeAllSuccess(t *testing.T) {
func TestKVPaymentsDBSubscribeAllSuccess(t *testing.T) {
t.Parallel()
db := initDB(t, true)
pControl := NewControlTower(channeldb.NewPaymentControl(db))
pControl := NewControlTower(channeldb.NewKVPaymentsDB(db))
// Initiate a payment.
info1, attempt1, preimg1, err := genInfo()
@@ -288,14 +288,14 @@ func TestPaymentControlSubscribeAllSuccess(t *testing.T) {
require.Equal(t, attempt2.Route, htlc2.Route, "unexpected htlc route.")
}
// TestPaymentControlSubscribeAllImmediate tests whether already inflight
// TestKVPaymentsDBSubscribeAllImmediate tests whether already inflight
// payments are reported at the start of the SubscribeAllPayments subscription.
func TestPaymentControlSubscribeAllImmediate(t *testing.T) {
func TestKVPaymentsDBSubscribeAllImmediate(t *testing.T) {
t.Parallel()
db := initDB(t, true)
pControl := NewControlTower(channeldb.NewPaymentControl(db))
pControl := NewControlTower(channeldb.NewKVPaymentsDB(db))
// Initiate a payment.
info, attempt, _, err := genInfo()
@@ -325,14 +325,14 @@ func TestPaymentControlSubscribeAllImmediate(t *testing.T) {
}
}
// TestPaymentControlUnsubscribeSuccess tests that when unsubscribed, there are
// TestKVPaymentsDBUnsubscribeSuccess tests that when unsubscribed, there are
// no more notifications to that specific subscription.
func TestPaymentControlUnsubscribeSuccess(t *testing.T) {
func TestKVPaymentsDBUnsubscribeSuccess(t *testing.T) {
t.Parallel()
db := initDB(t, true)
pControl := NewControlTower(channeldb.NewPaymentControl(db))
pControl := NewControlTower(channeldb.NewKVPaymentsDB(db))
subscription1, err := pControl.SubscribeAllPayments()
require.NoError(t, err, "expected subscribe to succeed, but got: %v")
@@ -396,12 +396,12 @@ func TestPaymentControlUnsubscribeSuccess(t *testing.T) {
require.Len(t, subscription2.Updates(), 0)
}
func testPaymentControlSubscribeFail(t *testing.T, registerAttempt,
func testKVPaymentsDBSubscribeFail(t *testing.T, registerAttempt,
keepFailedPaymentAttempts bool) {
db := initDB(t, keepFailedPaymentAttempts)
pControl := NewControlTower(channeldb.NewPaymentControl(db))
pControl := NewControlTower(channeldb.NewKVPaymentsDB(db))
// Initiate a payment.
info, attempt, _, err := genInfo()

View File

@@ -1127,7 +1127,7 @@ func newServer(ctx context.Context, cfg *Config, listenAddrs []net.Addr,
PathFindingConfig: pathFindingConfig,
}
paymentControl := channeldb.NewPaymentControl(dbs.ChanStateDB)
paymentControl := channeldb.NewKVPaymentsDB(dbs.ChanStateDB)
s.controlTower = routing.NewControlTower(paymentControl)