From 9662887d2f32b0f995a9bbff6ee878729ba87399 Mon Sep 17 00:00:00 2001 From: Olaoluwa Osuntokun Date: Tue, 17 Jan 2017 13:39:30 -0800 Subject: [PATCH] rpcserver+cmd/lncli: implement DecodePayReq This commit implements the newly added RPC to decode payment requests passed over the command line or directly via gRPC. With this tool, users can now examine payment requests they see in the wild for diagnostic or debugging purposes. --- cmd/lncli/commands.go | 32 ++++++++++++++++++++++++++++++++ cmd/lncli/main.go | 1 + lnd_test.go | 1 + rpcserver.go | 22 ++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/cmd/lncli/commands.go b/cmd/lncli/commands.go index a9fde0a1..15d86c49 100644 --- a/cmd/lncli/commands.go +++ b/cmd/lncli/commands.go @@ -531,6 +531,8 @@ func listChannels(ctx *cli.Context) error { return err } + // TODO(roasbeef): defer close the client for the all + printRespJson(resp) return nil @@ -955,3 +957,33 @@ func debugLevel(ctx *cli.Context) error { printRespJson(resp) return nil } + +var DecodePayReq = cli.Command{ + Name: "decodepayreq", + Usage: "decodepayreq --pay_req=[encoded_pay_req]", + Description: "Decode the passed payment request revealing the destination, payment hash and value of the payment request", + Flags: []cli.Flag{ + cli.StringFlag{ + Name: "pay_req", + Usage: "the zpay32 encoded payment request", + }, + }, + Action: decodePayReq, +} + +func decodePayReq(ctx *cli.Context) error { + ctxb := context.Background() + client := getClient(ctx) + + req := &lnrpc.PayReqString{ + PayReq: ctx.String("pay_req"), + } + + resp, err := client.DecodePayReq(ctxb, req) + if err != nil { + return err + } + + printRespJson(resp) + return nil +} diff --git a/cmd/lncli/main.go b/cmd/lncli/main.go index 21b61f94..c414155d 100644 --- a/cmd/lncli/main.go +++ b/cmd/lncli/main.go @@ -71,6 +71,7 @@ func main() { QueryRouteCommand, GetNetworkInfoCommand, DebugLevel, + DecodePayReq, } if err := app.Run(os.Args); err != nil { diff --git a/lnd_test.go b/lnd_test.go index 0a5a12b5..d428b7be 100644 --- a/lnd_test.go +++ b/lnd_test.go @@ -1020,6 +1020,7 @@ func testInvoiceSubscriptions(net *networkHarness, t *harnessTest) { // With the assertion above set up, send a payment from Alice to Bob // which should finalize and settle the invoice. + time.Sleep(time.Millisecond * 500) sendStream, err := net.Alice.SendPayment(ctxb) if err != nil { t.Fatalf("unable to create alice payment stream: %v", err) diff --git a/rpcserver.go b/rpcserver.go index 89a63056..b6ad8745 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1792,3 +1792,25 @@ func (r *rpcServer) DebugLevel(ctx context.Context, return &lnrpc.DebugLevelResponse{}, nil } + +// DecodePayReq takes an encoded payment request string and attempts to decode +// it, returning a full description of the conditions encoded within the +// payment request. +func (r *rpcServer) DecodePayReq(ctx context.Context, + req *lnrpc.PayReqString) (*lnrpc.PayReq, error) { + + // Fist we'll attempt to decode the payment request string, if the + // request is invalid or the checksum doesn't match, then we'll exit + // here with an error. + payReq, err := zpay32.Decode(req.PayReq) + if err != nil { + return nil, err + } + + dest := payReq.Destination.SerializeCompressed() + return &lnrpc.PayReq{ + Destination: hex.EncodeToString(dest), + PaymentHash: hex.EncodeToString(payReq.PaymentHash[:]), + NumSatoshis: int64(payReq.Amount), + }, nil +}