Skip to content

Commit 0bac0aa

Browse files
committed
accounts: start logging useful info from payment response handlers
1 parent 8b5a01f commit 0bac0aa

File tree

1 file changed

+94
-11
lines changed

1 file changed

+94
-11
lines changed

accounts/checkers.go

Lines changed: 94 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ func NewAccountChecker(service Service,
262262
}, sendResponseHandler, mid.PassThroughErrorHandler,
263263
),
264264
// routerrpc.Router/SendToRoute is deprecated.
265-
"/routerrpc.Router/SendToRouteV2": mid.NewRequestChecker(
265+
"/routerrpc.Router/SendToRouteV2": mid.NewFullChecker(
266266
&routerrpc.SendToRouteRequest{},
267267
&lnrpc.HTLCAttempt{},
268268
func(ctx context.Context,
@@ -272,10 +272,8 @@ func NewAccountChecker(service Service,
272272
ctx, service, r.PaymentHash, r.Route,
273273
)
274274
},
275-
// We don't get the payment hash in the response to this
276-
// call. So we can't optimize things and need to rely on
277-
// the payment being tracked by the hash sent in the
278-
// request.
275+
sendToRouteHTLCResponseHandler(service),
276+
mid.PassThroughErrorHandler,
279277
),
280278
"/lnrpc.Lightning/DecodePayReq": DecodePayReqPassThrough,
281279
"/lnrpc.Lightning/ListPayments": mid.NewResponseRewriter(
@@ -616,23 +614,42 @@ func checkSendResponse(ctx context.Context, service Service,
616614
status lnrpc.Payment_PaymentStatus, hash lntypes.Hash,
617615
fullAmt int64) (proto.Message, error) {
618616

619-
acct, err := AccountFromContext(ctx)
617+
log, acct, reqID, err := requestScopedValuesFromCtx(ctx)
620618
if err != nil {
621619
return nil, err
622620
}
623621

622+
reqVals, ok := service.GetValues(reqID)
623+
if !ok {
624+
return nil, nil
625+
}
626+
627+
if hash != reqVals.PaymentHash {
628+
return nil, fmt.Errorf("response hash did not match request " +
629+
"hash")
630+
}
631+
632+
log.Tracef("Handling response payment with hash: %s", hash)
633+
624634
// If we directly observe a failure, make sure
625635
// we stop tracking the payment and then exit
626636
// early.
627637
if status == lnrpc.Payment_FAILED {
638+
service.DeleteValues(reqID)
639+
628640
return nil, service.RemovePayment(hash)
629641
}
630642

631-
// If there is no immediate failure, make sure
632-
// we track the payment.
633-
return nil, service.TrackPayment(
634-
acct.ID, hash, lnwire.MilliSatoshi(fullAmt),
635-
)
643+
// If there is no immediate failure, make sure we track the payment.
644+
err = service.TrackPayment(acct.ID, hash, lnwire.MilliSatoshi(fullAmt))
645+
if err != nil {
646+
return nil, err
647+
}
648+
649+
// We can now delete the request values for this request ID.
650+
service.DeleteValues(reqID)
651+
652+
return nil, nil
636653
}
637654

638655
// checkSendToRoute checks if a payment can be sent to the route by making sure
@@ -688,3 +705,69 @@ func checkSendToRoute(ctx context.Context, service Service, paymentHash []byte,
688705
PaymentAmount: sendAmt,
689706
})
690707
}
708+
709+
// sendToRouteHTLCResponseHandler creates a response handler for the
710+
// SendToRouteV2 endpoint which is a streaming endpoint that may return multiple
711+
// HTLCAttempt updates.
712+
func sendToRouteHTLCResponseHandler(service Service) func(ctx context.Context,
713+
r *lnrpc.HTLCAttempt) (proto.Message, error) {
714+
715+
return func(ctx context.Context, r *lnrpc.HTLCAttempt) (proto.Message,
716+
error) {
717+
718+
log, acct, reqID, err := requestScopedValuesFromCtx(ctx)
719+
if err != nil {
720+
return nil, err
721+
}
722+
723+
// Since SendToRouteV2 is a streaming endpoint, we may get
724+
// multiple responses for it. If we have already handled it then
725+
// we would have deleted the request ID to hash mapping, and so
726+
// we can exit early here.
727+
reqValues, ok := service.GetValues(reqID)
728+
if !ok {
729+
return nil, nil
730+
}
731+
732+
log.Tracef("Handling response for payment with hash: %s and "+
733+
"amount: %d", reqValues.PaymentHash,
734+
reqValues.PaymentAmount)
735+
736+
// If the pre-image is provided, do a sanity check to make sure
737+
// that this does actually match the hash we stored for this
738+
// payment.
739+
if len(r.Preimage) != 0 {
740+
preimage, err := lntypes.MakePreimage(r.Preimage)
741+
if err != nil {
742+
return nil, err
743+
}
744+
745+
if !preimage.Matches(reqValues.PaymentHash) {
746+
return nil, fmt.Errorf("the preimage (%s) "+
747+
"returned by the response does not "+
748+
"match the payment hash (%s) of the "+
749+
"payment", preimage,
750+
reqValues.PaymentHash)
751+
}
752+
}
753+
754+
route := r.Route
755+
totalAmount := int64(0)
756+
if route != nil {
757+
totalAmount = route.TotalAmtMsat + route.TotalFeesMsat
758+
}
759+
760+
err = service.TrackPayment(
761+
acct.ID, reqValues.PaymentHash,
762+
lnwire.MilliSatoshi(totalAmount),
763+
)
764+
if err != nil {
765+
return nil, err
766+
}
767+
768+
// We can now delete the request values for this ID.
769+
service.DeleteValues(reqID)
770+
771+
return nil, nil
772+
}
773+
}

0 commit comments

Comments
 (0)