From 7ff50ccc5af9cb4c2d99dd7524710775442527f4 Mon Sep 17 00:00:00 2001 From: Joost Jager Date: Fri, 15 Nov 2019 14:26:38 +0100 Subject: [PATCH] lndclient: extend send payment parameters --- go.sum | 1 - lndclient/router_client.go | 104 +++++++++++++++++++++++++++++++++---- 2 files changed, 95 insertions(+), 10 deletions(-) diff --git a/go.sum b/go.sum index e947763..2a35e8d 100644 --- a/go.sum +++ b/go.sum @@ -129,7 +129,6 @@ github.com/lightninglabs/neutrino v0.11.0 h1:lPpYFCtsfJX2W5zI4pWycPmbbBdr7zU+Baf github.com/lightninglabs/neutrino v0.11.0/go.mod h1:CuhF0iuzg9Sp2HO6ZgXgayviFTn1QHdSTJlMncK80wg= github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a h1:GoWPN4i4jTKRxhVNh9a2vvBBO1Y2seiJB+SopUYoKyo= github.com/lightningnetwork/lightning-onion v0.0.0-20190909101754-850081b08b6a/go.mod h1:rigfi6Af/KqsF7Za0hOgcyq2PNH4AN70AaMRxcJkff4= -github.com/lightningnetwork/lnd v0.0.2 h1:actrQ68Mrj2atPV7A58FxPzP6Qjwvn0GqkxC9iC0Mlw= github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20191115230031-4d7a151b4763 h1:Eit9hH737th2WwnnVhkuxyMqgXce6keztGTtbDMLJ80= github.com/lightningnetwork/lnd v0.8.0-beta-rc3.0.20191115230031-4d7a151b4763/go.mod h1:Z7DDVIgvMgyb/4+btLeiU++xt49T35PNunXGCvAaxiE= github.com/lightningnetwork/lnd/queue v1.0.1 h1:jzJKcTy3Nj5lQrooJ3aaw9Lau3I0IwvQR5sqtjdv2R0= diff --git a/lndclient/router_client.go b/lndclient/router_client.go index f99d736..7b68d4f 100644 --- a/lndclient/router_client.go +++ b/lndclient/router_client.go @@ -6,19 +6,17 @@ import ( "fmt" "time" - "github.com/lightningnetwork/lnd/lnrpc" - "github.com/lightningnetwork/lnd/routing/route" - + "github.com/btcsuite/btcutil" "github.com/lightningnetwork/lnd/channeldb" - "google.golang.org/grpc/codes" - + "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnrpc/routerrpc" + "github.com/lightningnetwork/lnd/lntypes" "github.com/lightningnetwork/lnd/lnwire" + "github.com/lightningnetwork/lnd/routing/route" + "github.com/lightningnetwork/lnd/zpay32" "google.golang.org/grpc" + "google.golang.org/grpc/codes" "google.golang.org/grpc/status" - - "github.com/btcsuite/btcutil" - "github.com/lightningnetwork/lnd/lntypes" ) // RouterClient exposes payment functionality. @@ -44,11 +42,41 @@ type PaymentStatus struct { // SendPaymentRequest defines the payment parameters for a new payment. type SendPaymentRequest struct { - Invoice string + // Invoice is an encoded payment request. The individual payment + // parameters Target, Amount, PaymentHash, FinalCLTVDelta and RouteHints + // are only processed when the Invoice field is empty. + Invoice string + MaxFee btcutil.Amount MaxCltv *int32 OutgoingChannel *uint64 Timeout time.Duration + + // Target is the node in which the payment should be routed towards. + Target route.Vertex + + // Amount is the value of the payment to send through the network in + // satoshis. + Amount btcutil.Amount + + // PaymentHash is the r-hash value to use within the HTLC extended to + // the first hop. + PaymentHash [32]byte + + // FinalCLTVDelta is the CTLV expiry delta to use for the _final_ hop + // in the route. This means that the final hop will have a CLTV delta + // of at least: currentHeight + FinalCLTVDelta. + FinalCLTVDelta uint16 + + // RouteHints represents the different routing hints that can be used to + // assist a payment in reaching its destination successfully. These + // hints will act as intermediate hops along the route. + // + // NOTE: This is optional unless required by the payment. When providing + // multiple routes, ensure the hop hints within each route are chained + // together and sorted in forward order in order to reach the + // destination successfully. + RouteHints [][]zpay32.HopHint } // routerClient is a wrapper around the generated routerrpc proxy. @@ -84,6 +112,21 @@ func (r *routerClient) SendPayment(ctx context.Context, rpcReq.OutgoingChanId = *request.OutgoingChannel } + // Only if there is no payment request set, we will parse the individual + // payment parameters. + if request.Invoice == "" { + rpcReq.Dest = request.Target[:] + rpcReq.Amt = int64(request.Amount) + rpcReq.PaymentHash = request.PaymentHash[:] + rpcReq.FinalCltvDelta = int32(request.FinalCLTVDelta) + + routeHints, err := marshallRouteHints(request.RouteHints) + if err != nil { + return nil, nil, err + } + rpcReq.RouteHints = routeHints + } + stream, err := r.client.SendPayment(rpcCtx, rpcReq) if err != nil { return nil, nil, err @@ -237,3 +280,46 @@ func unmarshallHop(hop *lnrpc.Hop) (*route.Hop, error) { ChannelID: hop.ChanId, }, nil } + +// marshallRouteHints marshalls a list of route hints. +func marshallRouteHints(routeHints [][]zpay32.HopHint) ( + []*lnrpc.RouteHint, error) { + + rpcRouteHints := make([]*lnrpc.RouteHint, 0, len(routeHints)) + for _, routeHint := range routeHints { + rpcRouteHint := make( + []*lnrpc.HopHint, 0, len(routeHint), + ) + for _, hint := range routeHint { + rpcHint, err := marshallHopHint(hint) + if err != nil { + return nil, err + } + + rpcRouteHint = append(rpcRouteHint, rpcHint) + } + rpcRouteHints = append(rpcRouteHints, &lnrpc.RouteHint{ + HopHints: rpcRouteHint, + }) + } + + return rpcRouteHints, nil +} + +// marshallHopHint marshalls a single hop hint. +func marshallHopHint(hint zpay32.HopHint) (*lnrpc.HopHint, error) { + nodeID, err := route.NewVertexFromBytes( + hint.NodeID.SerializeCompressed(), + ) + if err != nil { + return nil, err + } + + return &lnrpc.HopHint{ + ChanId: hint.ChannelID, + CltvExpiryDelta: uint32(hint.CLTVExpiryDelta), + FeeBaseMsat: hint.FeeBaseMSat, + FeeProportionalMillionths: hint.FeeProportionalMillionths, + NodeId: nodeID.String(), + }, nil +}