mirror of
https://github.com/lightningnetwork/lnd.git
synced 2025-12-09 12:22:38 +01:00
routing/router: persist payment state machine
This commit makes the router use the ControlTower to drive the payment life cycle state machine, to keep track of active payments across restarts. This lets the router resume payments on startup, such that their final results can be handled and stored when ready.
This commit is contained in:
77
rpcserver.go
77
rpcserver.go
@@ -2,7 +2,6 @@ package lnd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"crypto/tls"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
@@ -2735,33 +2734,6 @@ func (r *rpcServer) SubscribeChannelEvents(req *lnrpc.ChannelEventSubscription,
|
||||
}
|
||||
}
|
||||
|
||||
// savePayment saves a successfully completed payment to the database for
|
||||
// historical record keeping.
|
||||
func (r *rpcServer) savePayment(route *route.Route,
|
||||
amount lnwire.MilliSatoshi, preImage []byte) error {
|
||||
|
||||
paymentPath := make([][33]byte, len(route.Hops))
|
||||
for i, hop := range route.Hops {
|
||||
hopPub := hop.PubKeyBytes
|
||||
copy(paymentPath[i][:], hopPub[:])
|
||||
}
|
||||
|
||||
payment := &channeldb.OutgoingPayment{
|
||||
Invoice: channeldb.Invoice{
|
||||
Terms: channeldb.ContractTerm{
|
||||
Value: amount,
|
||||
},
|
||||
CreationDate: time.Now(),
|
||||
},
|
||||
Path: paymentPath,
|
||||
Fee: route.TotalFees(),
|
||||
TimeLockLength: route.TotalTimeLock,
|
||||
}
|
||||
copy(payment.PaymentPreimage[:], preImage)
|
||||
|
||||
return r.server.chanDB.AddPayment(payment)
|
||||
}
|
||||
|
||||
// validatePayReqExpiry checks if the passed payment request has expired. In
|
||||
// the case it has expired, an error will be returned.
|
||||
func validatePayReqExpiry(payReq *zpay32.Invoice) error {
|
||||
@@ -3123,18 +3095,6 @@ func (r *rpcServer) dispatchPaymentIntent(
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Calculate amount paid to receiver.
|
||||
amt := route.TotalAmount - route.TotalFees()
|
||||
|
||||
// Save the completed payment to the database for record keeping
|
||||
// purposes.
|
||||
err := r.savePayment(route, amt, preImage[:])
|
||||
if err != nil {
|
||||
// We weren't able to save the payment, so we return the save
|
||||
// err, but a nil routing err.
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &paymentIntentResponse{
|
||||
Route: route,
|
||||
Preimage: preImage,
|
||||
@@ -4146,8 +4106,8 @@ func (r *rpcServer) ListPayments(ctx context.Context,
|
||||
|
||||
rpcsLog.Debugf("[ListPayments]")
|
||||
|
||||
payments, err := r.server.chanDB.FetchAllPayments()
|
||||
if err != nil && err != channeldb.ErrNoPaymentsCreated {
|
||||
payments, err := r.server.chanDB.FetchPayments()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -4155,24 +4115,37 @@ func (r *rpcServer) ListPayments(ctx context.Context,
|
||||
Payments: make([]*lnrpc.Payment, len(payments)),
|
||||
}
|
||||
for i, payment := range payments {
|
||||
path := make([]string, len(payment.Path))
|
||||
for i, hop := range payment.Path {
|
||||
path[i] = hex.EncodeToString(hop[:])
|
||||
// If a payment attempt has been made we can fetch the route.
|
||||
// Otherwise we'll just populate the RPC response with an empty
|
||||
// one.
|
||||
var route route.Route
|
||||
if payment.Attempt != nil {
|
||||
route = payment.Attempt.Route
|
||||
}
|
||||
path := make([]string, len(route.Hops))
|
||||
for i, hop := range route.Hops {
|
||||
path[i] = hex.EncodeToString(hop.PubKeyBytes[:])
|
||||
}
|
||||
|
||||
msatValue := int64(payment.Terms.Value)
|
||||
satValue := int64(payment.Terms.Value.ToSatoshis())
|
||||
// If this payment is settled, the preimage will be available.
|
||||
var preimage lntypes.Preimage
|
||||
if payment.PaymentPreimage != nil {
|
||||
preimage = *payment.PaymentPreimage
|
||||
}
|
||||
|
||||
paymentHash := sha256.Sum256(payment.PaymentPreimage[:])
|
||||
msatValue := int64(payment.Info.Value)
|
||||
satValue := int64(payment.Info.Value.ToSatoshis())
|
||||
|
||||
paymentHash := payment.Info.PaymentHash
|
||||
paymentsResp.Payments[i] = &lnrpc.Payment{
|
||||
PaymentHash: hex.EncodeToString(paymentHash[:]),
|
||||
Value: satValue,
|
||||
ValueMsat: msatValue,
|
||||
ValueSat: satValue,
|
||||
CreationDate: payment.CreationDate.Unix(),
|
||||
CreationDate: payment.Info.CreationDate.Unix(),
|
||||
Path: path,
|
||||
Fee: int64(payment.Fee.ToSatoshis()),
|
||||
PaymentPreimage: hex.EncodeToString(payment.PaymentPreimage[:]),
|
||||
Fee: int64(route.TotalFees().ToSatoshis()),
|
||||
PaymentPreimage: hex.EncodeToString(preimage[:]),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4185,7 +4158,7 @@ func (r *rpcServer) DeleteAllPayments(ctx context.Context,
|
||||
|
||||
rpcsLog.Debugf("[DeleteAllPayments]")
|
||||
|
||||
if err := r.server.chanDB.DeleteAllPayments(); err != nil {
|
||||
if err := r.server.chanDB.DeletePayments(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user