Browse Source

sendpay: provide 'bolt11' parameter.

Without this, there's no proof of payment, since it is the signed invoice
that make the receipt valid.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
pr-2391
Rusty Russell 6 years ago
parent
commit
5e14274f41
  1. 1
      CHANGELOG.md
  2. 6
      doc/lightning-sendpay.7
  3. 7
      doc/lightning-sendpay.7.txt
  4. 14
      lightningd/pay.c
  5. 2
      wallet/db.c
  6. 20
      wallet/wallet.c
  7. 2
      wallet/wallet.h

1
CHANGELOG.md

@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- JSON API: `listchannels` now takes a `source` option to filter by node id. - JSON API: `listchannels` now takes a `source` option to filter by node id.
- JSON API: New command `paystatus` gives detailed information on `pay` commands. - JSON API: New command `paystatus` gives detailed information on `pay` commands.
- JSON API: `getroute` `riskfactor` argument is simplified; `pay` now defaults to setting it to 10. - JSON API: `getroute` `riskfactor` argument is simplified; `pay` now defaults to setting it to 10.
- JSON API: `sendpay` now takes a `bolt11` field, and it's returned in `listpayments` and `waitsendpay`.
- pylightning: New class 'Millisatoshi' can be used for JSON API, and new '_msat' fields are turned into this on reading. - pylightning: New class 'Millisatoshi' can be used for JSON API, and new '_msat' fields are turned into this on reading.
- JSON API: `fundchannel` and `withdraw` now have a new parameter `minconf` that limits coinselection to outputs that have at least `minconf` confirmations (default 1). (#2380) - JSON API: `fundchannel` and `withdraw` now have a new parameter `minconf` that limits coinselection to outputs that have at least `minconf` confirmations (default 1). (#2380)
- JSON API: `listfunds` now displays addresses for all outputs owned by the wallet (#2387) - JSON API: `listfunds` now displays addresses for all outputs owned by the wallet (#2387)

6
doc/lightning-sendpay.7

@ -28,10 +28,10 @@
.\" * MAIN CONTENT STARTS HERE * .\" * MAIN CONTENT STARTS HERE *
.\" ----------------------------------------------------------------- .\" -----------------------------------------------------------------
.SH "NAME" .SH "NAME"
lightning-sendpay \- Command for sending a payment via a route\&. lightning-sendpay \- Low\-level command for sending a payment via a route\&.
.SH "SYNOPSIS" .SH "SYNOPSIS"
.sp .sp
\fBsendpay\fR \fIroute\fR \fIpayment_hash\fR [\fIdescription\fR] [\fImsatoshi\fR] \fBsendpay\fR \fIroute\fR \fIpayment_hash\fR [\fIdescription\fR] [\fImsatoshi\fR] [\fIbolt11\fR]
.SH "DESCRIPTION" .SH "DESCRIPTION"
.sp .sp
The \fBsendpay\fR RPC command attempts to send funds associated with the given \fIpayment_hash\fR, along a route to the final destination in the route\&. The \fBsendpay\fR RPC command attempts to send funds associated with the given \fIpayment_hash\fR, along a route to the final destination in the route\&.
@ -40,7 +40,7 @@ Generally, a client would call lightning\-getroute(7) to resolve a route, then u
.sp .sp
The response will occur when the payment is on its way to the destination\&. The \fBsendpay\fR RPC command does not wait for definite success or definite failure of the payment\&. Instead, use the \fBwaitsendpay\fR RPC command to poll or wait for definite success or definite failure\&. The response will occur when the payment is on its way to the destination\&. The \fBsendpay\fR RPC command does not wait for definite success or definite failure of the payment\&. Instead, use the \fBwaitsendpay\fR RPC command to poll or wait for definite success or definite failure\&.
.sp .sp
The \fIdescription\fR parameter, if provided, will be returned in \fIwaitsendpay\fR and \fIlistpayments\fR results\&. The \fIdescription\fR and \fIbolt11\fR parameters, if provided, will be returned in \fIwaitsendpay\fR and \fIlistpayments\fR results\&.
.sp .sp
The \fImsatoshi\fR amount, if provided, is the amount that will be recorded as the target payment value\&. If not specified, it will be the final amount to the destination\&. If specified, then the final amount at the destination must be from the specified \fImsatoshi\fR to twice the specified \fImsatoshi\fR, inclusive\&. This is intended to obscure payments by overpaying slightly at the destination; the actual target payment is what should be specified as the \fImsatoshi\fR argument\&. \fImsatoshi\fR is in millisatoshi precision; it can be a whole number, or a whole number ending in \fImsat\fR or \fIsat\fR, or a number with three decimal places ending in \fIsat\fR, or a number with 1 to 11 decimal places ending in \fIbtc\fR\&. The \fImsatoshi\fR amount, if provided, is the amount that will be recorded as the target payment value\&. If not specified, it will be the final amount to the destination\&. If specified, then the final amount at the destination must be from the specified \fImsatoshi\fR to twice the specified \fImsatoshi\fR, inclusive\&. This is intended to obscure payments by overpaying slightly at the destination; the actual target payment is what should be specified as the \fImsatoshi\fR argument\&. \fImsatoshi\fR is in millisatoshi precision; it can be a whole number, or a whole number ending in \fImsat\fR or \fIsat\fR, or a number with three decimal places ending in \fIsat\fR, or a number with 1 to 11 decimal places ending in \fIbtc\fR\&.
.sp .sp

7
doc/lightning-sendpay.7.txt

@ -4,11 +4,11 @@ LIGHTNING-SENDPAY(7)
NAME NAME
---- ----
lightning-sendpay - Command for sending a payment via a route. lightning-sendpay - Low-level command for sending a payment via a route.
SYNOPSIS SYNOPSIS
-------- --------
*sendpay* 'route' 'payment_hash' ['description'] ['msatoshi'] *sendpay* 'route' 'payment_hash' ['description'] ['msatoshi'] ['bolt11']
DESCRIPTION DESCRIPTION
----------- -----------
@ -27,7 +27,7 @@ definite failure of the payment.
Instead, use the *waitsendpay* RPC command to poll or wait for Instead, use the *waitsendpay* RPC command to poll or wait for
definite success or definite failure. definite success or definite failure.
The 'description' parameter, if provided, will be returned in The 'description' and 'bolt11' parameters, if provided, will be returned in
'waitsendpay' and 'listpayments' results. 'waitsendpay' and 'listpayments' results.
The 'msatoshi' amount, if provided, is the amount that will be The 'msatoshi' amount, if provided, is the amount that will be
@ -44,7 +44,6 @@ be a whole number, or a whole number ending in 'msat' or 'sat', or a
number with three decimal places ending in 'sat', or a number with 1 number with three decimal places ending in 'sat', or a number with 1
to 11 decimal places ending in 'btc'. to 11 decimal places ending in 'btc'.
Once a payment has succeeded, calls to *sendpay* with the same 'payment_hash' Once a payment has succeeded, calls to *sendpay* with the same 'payment_hash'
but a different 'msatoshi' or destination will fail; this prevents but a different 'msatoshi' or destination will fail; this prevents
accidental multiple payments. accidental multiple payments.

14
lightningd/pay.c

@ -101,6 +101,8 @@ json_add_payment_fields(struct json_stream *response,
sizeof(*t->payment_preimage)); sizeof(*t->payment_preimage));
if (t->description) if (t->description)
json_add_string(response, "description", t->description); json_add_string(response, "description", t->description);
if (t->bolt11)
json_add_string(response, "bolt11", t->bolt11);
} }
static struct command_result *sendpay_success(struct command *cmd, static struct command_result *sendpay_success(struct command *cmd,
@ -580,7 +582,8 @@ send_payment(struct lightningd *ld,
const struct sha256 *rhash, const struct sha256 *rhash,
const struct route_hop *route, const struct route_hop *route,
struct amount_msat msat, struct amount_msat msat,
const char *description TAKES) const char *description TAKES,
const char *b11str TAKES)
{ {
const u8 *onion; const u8 *onion;
u8 sessionkey[32]; u8 sessionkey[32];
@ -720,6 +723,10 @@ send_payment(struct lightningd *ld,
payment->description = tal_strdup(payment, description); payment->description = tal_strdup(payment, description);
else else
payment->description = NULL; payment->description = NULL;
if (b11str != NULL)
payment->bolt11 = tal_strdup(payment, b11str);
else
payment->bolt11 = NULL;
/* We write this into db when HTLC is actually sent. */ /* We write this into db when HTLC is actually sent. */
wallet_payment_setup(ld->wallet, payment); wallet_payment_setup(ld->wallet, payment);
@ -743,7 +750,7 @@ static struct command_result *json_sendpay(struct command *cmd,
struct sha256 *rhash; struct sha256 *rhash;
struct route_hop *route; struct route_hop *route;
struct amount_msat *msat; struct amount_msat *msat;
const char *description; const char *description, *b11str;
struct command_result *res; struct command_result *res;
if (!param(cmd, buffer, params, if (!param(cmd, buffer, params,
@ -751,6 +758,7 @@ static struct command_result *json_sendpay(struct command *cmd,
p_req("payment_hash", param_sha256, &rhash), p_req("payment_hash", param_sha256, &rhash),
p_opt("description", param_escaped_string, &description), p_opt("description", param_escaped_string, &description),
p_opt("msatoshi", param_msat, &msat), p_opt("msatoshi", param_msat, &msat),
p_opt("bolt11", param_string, &b11str),
NULL)) NULL))
return command_param_failed(); return command_param_failed();
@ -836,7 +844,7 @@ static struct command_result *json_sendpay(struct command *cmd,
res = send_payment(cmd->ld, cmd, rhash, route, res = send_payment(cmd->ld, cmd, rhash, route,
msat ? *msat : route[routetok->size-1].amount, msat ? *msat : route[routetok->size-1].amount,
description); description, b11str);
if (res) if (res)
return res; return res;
return command_still_pending(cmd); return command_still_pending(cmd);

2
wallet/db.c

@ -359,6 +359,8 @@ char *dbmigrations[] = {
/* Fix dangling peers with no channels. */ /* Fix dangling peers with no channels. */
"DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);", "DELETE FROM peers WHERE id NOT IN (SELECT peer_id FROM channels);",
"ALTER TABLE outputs ADD scriptpubkey BLOB;", "ALTER TABLE outputs ADD scriptpubkey BLOB;",
/* Keep bolt11 string for payments. */
"ALTER TABLE payments ADD bolt11 TEXT;",
NULL, NULL,
}; };

20
wallet/wallet.c

@ -1722,8 +1722,9 @@ void wallet_payment_store(struct wallet *wallet,
" route_nodes," " route_nodes,"
" route_channels," " route_channels,"
" msatoshi_sent," " msatoshi_sent,"
" description" " description,"
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"); " bolt11"
") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);");
sqlite3_bind_int(stmt, 1, payment->status); sqlite3_bind_int(stmt, 1, payment->status);
sqlite3_bind_sha256(stmt, 2, &payment->payment_hash); sqlite3_bind_sha256(stmt, 2, &payment->payment_hash);
@ -1745,6 +1746,13 @@ void wallet_payment_store(struct wallet *wallet,
else else
sqlite3_bind_null(stmt, 10); sqlite3_bind_null(stmt, 10);
if (payment->bolt11 != NULL)
sqlite3_bind_text(stmt, 11, payment->bolt11,
strlen(payment->bolt11),
SQLITE_TRANSIENT);
else
sqlite3_bind_null(stmt, 11);
db_exec_prepared(wallet->db, stmt); db_exec_prepared(wallet->db, stmt);
tal_free(payment); tal_free(payment);
@ -1804,6 +1812,12 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
else else
payment->description = NULL; payment->description = NULL;
if (sqlite3_column_type(stmt, 12) != SQLITE_NULL)
payment->bolt11 = tal_strdup(payment,
(const char *)sqlite3_column_text(stmt, 12));
else
payment->bolt11 = NULL;
return payment; return payment;
} }
@ -1811,7 +1825,7 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
#define PAYMENT_FIELDS \ #define PAYMENT_FIELDS \
"id, status, destination, msatoshi, payment_hash, timestamp, " \ "id, status, destination, msatoshi, payment_hash, timestamp, " \
"payment_preimage, path_secrets, route_nodes, route_channels, " \ "payment_preimage, path_secrets, route_nodes, route_channels, " \
"msatoshi_sent, description " "msatoshi_sent, description, bolt11 "
struct wallet_payment * struct wallet_payment *
wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet, wallet_payment_by_hash(const tal_t *ctx, struct wallet *wallet,

2
wallet/wallet.h

@ -224,6 +224,8 @@ struct wallet_payment {
struct secret *path_secrets; struct secret *path_secrets;
struct pubkey *route_nodes; struct pubkey *route_nodes;
struct short_channel_id *route_channels; struct short_channel_id *route_channels;
/* bolt11 string; NULL for old payments. */
const char *bolt11;
/* The description of the payment. Must support `tal_len` */ /* The description of the payment. Must support `tal_len` */
const char *description; const char *description;

Loading…
Cancel
Save