mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-12-05 02:11:10 +01:00
channeldb+routing: expose HTLCs in payment subscriptions
This commit modifies the FetchPayment method to return MPPayment structs converted from the legacy on-disk format. This allows us to attach the HTLCs to the events given to clients subscribing to the outcome of an HTLC. This commit also bubbles up to the routerrpc/router_server, by populating HTLCAttempts in the response and extracting the legacy route field from the HTLCAttempts.
This commit is contained in:
@@ -6,7 +6,6 @@ import (
|
||||
|
||||
"github.com/lightningnetwork/lnd/channeldb"
|
||||
"github.com/lightningnetwork/lnd/lntypes"
|
||||
"github.com/lightningnetwork/lnd/routing/route"
|
||||
)
|
||||
|
||||
// ControlTower tracks all outgoing payments made, whose primary purpose is to
|
||||
@@ -52,10 +51,6 @@ type PaymentResult struct {
|
||||
// Success indicates whether the payment was successful.
|
||||
Success bool
|
||||
|
||||
// Route is the (last) route attempted to send the HTLC. It is only set
|
||||
// for successful payments.
|
||||
Route *route.Route
|
||||
|
||||
// Preimage is the preimage of a successful payment. This serves as a
|
||||
// proof of payment. It is only set for successful payments.
|
||||
Preimage lntypes.Preimage
|
||||
@@ -63,6 +58,10 @@ type PaymentResult struct {
|
||||
// FailureReason is a failure reason code indicating the reason the
|
||||
// payment failed. It is only set for failed payments.
|
||||
FailureReason channeldb.FailureReason
|
||||
|
||||
// HTLCs is a list of HTLCs that have been attempted in order to settle
|
||||
// the payment.
|
||||
HTLCs []channeldb.HTLCAttempt
|
||||
}
|
||||
|
||||
// controlTower is persistent implementation of ControlTower to restrict
|
||||
@@ -107,46 +106,46 @@ func (p *controlTower) RegisterAttempt(paymentHash lntypes.Hash,
|
||||
func (p *controlTower) Success(paymentHash lntypes.Hash,
|
||||
preimage lntypes.Preimage) error {
|
||||
|
||||
route, err := p.db.Success(paymentHash, preimage)
|
||||
payment, err := p.db.Success(paymentHash, preimage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Notify subscribers of success event.
|
||||
p.notifyFinalEvent(
|
||||
paymentHash, createSuccessResult(route, preimage),
|
||||
paymentHash, createSuccessResult(payment.HTLCs),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// createSuccessResult creates a success result to send to subscribers.
|
||||
func createSuccessResult(rt *route.Route,
|
||||
preimage lntypes.Preimage) *PaymentResult {
|
||||
func createSuccessResult(htlcs []channeldb.HTLCAttempt) *PaymentResult {
|
||||
// Extract any preimage from the list of HTLCs.
|
||||
var preimage lntypes.Preimage
|
||||
for _, htlc := range htlcs {
|
||||
if htlc.Settle != nil {
|
||||
preimage = htlc.Settle.Preimage
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return &PaymentResult{
|
||||
Success: true,
|
||||
Preimage: preimage,
|
||||
Route: rt,
|
||||
HTLCs: htlcs,
|
||||
}
|
||||
}
|
||||
|
||||
// createFailResult creates a failed result to send to subscribers.
|
||||
func createFailedResult(rt *route.Route,
|
||||
func createFailedResult(htlcs []channeldb.HTLCAttempt,
|
||||
reason channeldb.FailureReason) *PaymentResult {
|
||||
|
||||
result := &PaymentResult{
|
||||
return &PaymentResult{
|
||||
Success: false,
|
||||
FailureReason: reason,
|
||||
HTLCs: htlcs,
|
||||
}
|
||||
|
||||
// In case of incorrect payment details, set the route. This can be used
|
||||
// for probing and to extract a fee estimate from the route.
|
||||
if reason == channeldb.FailureReasonPaymentDetails {
|
||||
result.Route = rt
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// Fail transitions a payment into the Failed state, and records the reason the
|
||||
@@ -156,14 +155,16 @@ func createFailedResult(rt *route.Route,
|
||||
func (p *controlTower) Fail(paymentHash lntypes.Hash,
|
||||
reason channeldb.FailureReason) error {
|
||||
|
||||
route, err := p.db.Fail(paymentHash, reason)
|
||||
payment, err := p.db.Fail(paymentHash, reason)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Notify subscribers of fail event.
|
||||
p.notifyFinalEvent(
|
||||
paymentHash, createFailedResult(route, reason),
|
||||
paymentHash, createFailedResult(
|
||||
payment.HTLCs, reason,
|
||||
),
|
||||
)
|
||||
|
||||
return nil
|
||||
@@ -213,20 +214,14 @@ func (p *controlTower) SubscribePayment(paymentHash lntypes.Hash) (
|
||||
// a subscriber, because we can send the result on the channel
|
||||
// immediately.
|
||||
case channeldb.StatusSucceeded:
|
||||
event = *createSuccessResult(
|
||||
&payment.Attempt.Route, *payment.Preimage,
|
||||
)
|
||||
event = *createSuccessResult(payment.HTLCs)
|
||||
|
||||
// Payment already failed. It is not necessary to register as a
|
||||
// subscriber, because we can send the result on the channel
|
||||
// immediately.
|
||||
case channeldb.StatusFailed:
|
||||
var route *route.Route
|
||||
if payment.Attempt != nil {
|
||||
route = &payment.Attempt.Route
|
||||
}
|
||||
event = *createFailedResult(
|
||||
route, *payment.Failure,
|
||||
payment.HTLCs, *payment.FailureReason,
|
||||
)
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user