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:
Conner Fromknecht
2019-11-08 03:39:51 -08:00
parent 68916eb4b7
commit 063f24f2ed
6 changed files with 143 additions and 86 deletions

View File

@@ -8,7 +8,6 @@ import (
"github.com/coreos/bbolt"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/routing/route"
)
var (
@@ -192,16 +191,17 @@ func (p *PaymentControl) RegisterAttempt(paymentHash lntypes.Hash,
// duplicate payments to the same payment hash. The provided preimage is
// atomically saved to the DB for record keeping.
func (p *PaymentControl) Success(paymentHash lntypes.Hash,
preimage lntypes.Preimage) (*route.Route, error) {
preimage lntypes.Preimage) (*MPPayment, error) {
var (
updateErr error
route *route.Route
payment *MPPayment
)
err := p.db.Batch(func(tx *bbolt.Tx) error {
// Reset the update error, to avoid carrying over an error
// from a previous execution of the batched db transaction.
updateErr = nil
payment = nil
bucket, err := fetchPaymentBucket(tx, paymentHash)
if err == ErrPaymentNotInitiated {
@@ -225,20 +225,14 @@ func (p *PaymentControl) Success(paymentHash lntypes.Hash,
}
// Retrieve attempt info for the notification.
attempt, err := fetchPaymentAttempt(bucket)
if err != nil {
return err
}
route = &attempt.Route
return nil
payment, err = fetchPayment(bucket)
return err
})
if err != nil {
return nil, err
}
return route, updateErr
return payment, updateErr
}
// Fail transitions a payment into the Failed state, and records the reason the
@@ -246,16 +240,17 @@ func (p *PaymentControl) Success(paymentHash lntypes.Hash,
// its next call for this payment hash, allowing the switch to make a
// subsequent payment.
func (p *PaymentControl) Fail(paymentHash lntypes.Hash,
reason FailureReason) (*route.Route, error) {
reason FailureReason) (*MPPayment, error) {
var (
updateErr error
route *route.Route
payment *MPPayment
)
err := p.db.Batch(func(tx *bbolt.Tx) error {
// Reset the update error, to avoid carrying over an error
// from a previous execution of the batched db transaction.
updateErr = nil
payment = nil
bucket, err := fetchPaymentBucket(tx, paymentHash)
if err == ErrPaymentNotInitiated {
@@ -279,28 +274,21 @@ func (p *PaymentControl) Fail(paymentHash lntypes.Hash,
}
// Retrieve attempt info for the notification, if available.
attempt, err := fetchPaymentAttempt(bucket)
if err != nil && err != errNoAttemptInfo {
return err
}
if err != errNoAttemptInfo {
route = &attempt.Route
}
return nil
payment, err = fetchPayment(bucket)
return err
})
if err != nil {
return nil, err
}
return route, updateErr
return payment, updateErr
}
// FetchPayment returns information about a payment from the database.
func (p *PaymentControl) FetchPayment(paymentHash lntypes.Hash) (
*Payment, error) {
*MPPayment, error) {
var payment *Payment
var payment *MPPayment
err := p.db.View(func(tx *bbolt.Tx) error {
bucket, err := fetchPaymentBucket(tx, paymentHash)
if err != nil {

View File

@@ -14,7 +14,6 @@ import (
"github.com/coreos/bbolt"
"github.com/davecgh/go-spew/spew"
"github.com/lightningnetwork/lnd/lntypes"
"github.com/lightningnetwork/lnd/routing/route"
)
func initDB() (*DB, error) {
@@ -132,16 +131,22 @@ func TestPaymentControlSwitchFail(t *testing.T) {
)
// Verifies that status was changed to StatusSucceeded.
var route *route.Route
route, err = pControl.Success(info.PaymentHash, preimg)
var payment *MPPayment
payment, err = pControl.Success(info.PaymentHash, preimg)
if err != nil {
t.Fatalf("error shouldn't have been received, got: %v", err)
}
err = assertRouteEqual(route, &attempt.Route)
if len(payment.HTLCs) != 1 {
t.Fatalf("payment should have one htlc, got: %d",
len(payment.HTLCs))
}
err = assertRouteEqual(&payment.HTLCs[0].Route, &attempt.Route)
if err != nil {
t.Fatalf("unexpected route returned: %v vs %v: %v",
spew.Sdump(attempt.Route), spew.Sdump(*route), err)
spew.Sdump(attempt.Route),
spew.Sdump(payment.HTLCs[0].Route), err)
}
assertPaymentStatus(t, db, info.PaymentHash, StatusSucceeded)

View File

@@ -337,7 +337,7 @@ func (db *DB) FetchPayments() ([]*MPPayment, error) {
return err
}
payments = append(payments, p.ToMPPayment())
payments = append(payments, p)
// For older versions of lnd, duplicate payments to a
// payment has was possible. These will be found in a
@@ -362,7 +362,7 @@ func (db *DB) FetchPayments() ([]*MPPayment, error) {
return err
}
payments = append(payments, p.ToMPPayment())
payments = append(payments, p)
return nil
})
})
@@ -379,7 +379,7 @@ func (db *DB) FetchPayments() ([]*MPPayment, error) {
return payments, nil
}
func fetchPayment(bucket *bbolt.Bucket) (*Payment, error) {
func fetchPayment(bucket *bbolt.Bucket) (*MPPayment, error) {
var (
err error
p = &Payment{}
@@ -434,7 +434,7 @@ func fetchPayment(bucket *bbolt.Bucket) (*Payment, error) {
p.Failure = &reason
}
return p, nil
return p.ToMPPayment(), nil
}
// DeletePayments deletes all completed and failed payments from the DB.