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 committed 2025-08-14 19:53:15 +02:00
1 parent 77a6b577eb
commit 03af9858d2
26 files changed
+1075 -948

No files matched your search

+24 -23
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 {