Browse Source

pay, wallet: rename internal `bolt11` vars to `invstring`.

And handle bolt12 strings if EXPERIMENTAL_FEATURES.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa
Rusty Russell 4 years ago
committed by Christian Decker
parent
commit
a33e39b7e8
  1. 70
      lightningd/pay.c
  2. 2
      plugins/keysend.c
  3. 18
      plugins/libplugin-pay.c
  4. 8
      plugins/libplugin-pay.h
  5. 80
      plugins/pay.c
  6. 2
      tests/test_plugin.py
  7. 2
      wallet/db_postgres_sqlgen.c
  8. 2
      wallet/db_sqlite3_sqlgen.c
  9. 2
      wallet/statements_gettextgen.po
  10. 8
      wallet/wallet.c
  11. 4
      wallet/wallet.h

70
lightningd/pay.c

@ -2,6 +2,10 @@
#include <ccan/str/hex/hex.h>
#include <ccan/tal/str/str.h>
#include <common/bolt11.h>
#if EXPERIMENTAL_FEATURES
#include <common/bolt12.h>
#include <common/bolt12_merkle.h>
#endif
#include <common/json_command.h>
#include <common/json_helpers.h>
#include <common/jsonrpc_errors.h>
@ -151,8 +155,14 @@ void json_add_payment_fields(struct json_stream *response,
t->payment_preimage);
if (t->label)
json_add_string(response, "label", t->label);
if (t->bolt11)
json_add_string(response, "bolt11", t->bolt11);
if (t->invstring) {
#if EXPERIMENTAL_FEATURES
if (strstarts(t->invstring, "lni"))
json_add_string(response, "bolt12", t->invstring);
else
#endif
json_add_string(response, "bolt11", t->invstring);
}
if (t->failonion)
json_add_hex(response, "erroronion", t->failonion,
@ -858,7 +868,7 @@ send_payment_core(struct lightningd *ld,
struct amount_msat msat,
struct amount_msat total_msat,
const char *label TAKES,
const char *b11str TAKES,
const char *invstring TAKES,
const struct onionpacket *packet,
const struct node_id *destination,
struct node_id *route_nodes TAKES,
@ -1078,10 +1088,10 @@ send_payment_core(struct lightningd *ld,
payment->label = tal_strdup(payment, label);
else
payment->label = NULL;
if (b11str != NULL)
payment->bolt11 = tal_strdup(payment, b11str);
if (invstring != NULL)
payment->invstring = tal_strdup(payment, invstring);
else
payment->bolt11 = NULL;
payment->invstring = NULL;
if (local_offer_id)
payment->local_offer_id = tal_dup(payment, struct sha256, local_offer_id);
else
@ -1103,7 +1113,7 @@ send_payment(struct lightningd *ld,
struct amount_msat msat,
struct amount_msat total_msat,
const char *label TAKES,
const char *b11str TAKES,
const char *invstring TAKES,
const struct sha256 *local_offer_id,
const struct secret *payment_secret)
{
@ -1186,7 +1196,7 @@ send_payment(struct lightningd *ld,
n_hops, type_to_string(tmpctx, struct amount_msat, &msat));
packet = create_onionpacket(tmpctx, path, ROUTING_INFO_SIZE, &path_secrets);
return send_payment_core(ld, cmd, rhash, partid, &route[0],
msat, total_msat, label, b11str,
msat, total_msat, label, invstring,
packet, &ids[n_hops - 1], ids,
channels, path_secrets, local_offer_id);
}
@ -1268,7 +1278,7 @@ static struct command_result *json_sendonion(struct command *cmd,
struct route_hop *first_hop;
struct sha256 *payment_hash;
struct lightningd *ld = cmd->ld;
const char *label, *b11str;
const char *label, *invstring;
struct node_id *destination;
struct secret *path_secrets;
struct amount_msat *msat;
@ -1282,7 +1292,8 @@ static struct command_result *json_sendonion(struct command *cmd,
p_opt("label", param_escaped_string, &label),
p_opt("shared_secrets", param_secrets_array, &path_secrets),
p_opt_def("partid", param_u64, &partid, 0),
p_opt("bolt11", param_string, &b11str),
/* FIXME: paramter should be invstring now */
p_opt("bolt11", param_string, &invstring),
p_opt_def("msatoshi", param_msat, &msat, AMOUNT_MSAT(0)),
p_opt("destination", param_node_id, &destination),
#if EXPERIMENTAL_FEATURES
@ -1301,7 +1312,7 @@ static struct command_result *json_sendonion(struct command *cmd,
return send_payment_core(ld, cmd, payment_hash, *partid,
first_hop, *msat, AMOUNT_MSAT(0),
label, b11str, packet, destination, NULL, NULL,
label, invstring, packet, destination, NULL, NULL,
path_secrets, local_offer_id);
}
@ -1425,7 +1436,7 @@ static struct command_result *json_sendpay(struct command *cmd,
struct sha256 *rhash;
struct route_hop *route;
struct amount_msat *msat;
const char *b11str, *label;
const char *invstring, *label;
u64 *partid;
struct secret *payment_secret;
struct sha256 *local_offer_id = NULL;
@ -1436,7 +1447,8 @@ static struct command_result *json_sendpay(struct command *cmd,
p_req("payment_hash", param_sha256, &rhash),
p_opt("label", param_escaped_string, &label),
p_opt("msatoshi", param_msat, &msat),
p_opt("bolt11", param_string, &b11str),
/* FIXME: paramter should be invstring now */
p_opt("bolt11", param_string, &invstring),
p_opt("payment_secret", param_secret, &payment_secret),
p_opt_def("partid", param_u64, &partid, 0),
#if EXPERIMENTAL_FEATURES
@ -1485,7 +1497,7 @@ static struct command_result *json_sendpay(struct command *cmd,
route,
final_amount,
msat ? *msat : final_amount,
label, b11str, local_offer_id, payment_secret);
label, invstring, local_offer_id, payment_secret);
}
static const struct json_command sendpay_command = {
@ -1546,31 +1558,43 @@ static struct command_result *json_listsendpays(struct command *cmd,
const struct wallet_payment **payments;
struct json_stream *response;
struct sha256 *rhash;
const char *b11str;
const char *invstring;
if (!param(cmd, buffer, params,
p_opt("bolt11", param_string, &b11str),
/* FIXME: paramter should be invstring now */
p_opt("bolt11", param_string, &invstring),
p_opt("payment_hash", param_sha256, &rhash),
NULL))
return command_param_failed();
if (rhash && b11str) {
if (rhash && invstring) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Can only specify one of"
" {bolt11} or {payment_hash}");
}
if (b11str) {
if (invstring) {
struct bolt11 *b11;
char *fail;
b11 = bolt11_decode(cmd, b11str, cmd->ld->our_features, NULL,
b11 = bolt11_decode(cmd, invstring, cmd->ld->our_features, NULL,
chainparams, &fail);
if (!b11) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid bolt11: %s", fail);
if (b11) {
rhash = &b11->payment_hash;
} else {
#if EXPERIMENTAL_FEATURES
struct tlv_invoice *b12;
b12 = invoice_decode(cmd, invstring, strlen(invstring),
cmd->ld->our_features,
chainparams, &fail);
if (b12 && b12->payment_hash)
rhash = b12->payment_hash;
else
#endif
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"Invalid invstring: %s", fail);
}
rhash = &b11->payment_hash;
}
payments = wallet_payment_list(cmd, cmd->ld->wallet, rhash);

2
plugins/keysend.c

@ -159,7 +159,7 @@ static struct command_result *json_keysend(struct command *cmd, const char *buf,
p->routes = NULL;
p->min_final_cltv_expiry = DEFAULT_FINAL_CLTV_DELTA;
p->features = NULL;
p->bolt11 = NULL;
p->invstring = NULL;
p->why = "Initial attempt";
p->constraints.cltv_budget = *maxdelay;
p->deadline = timeabs_add(time_now(), time_from_sec(*retryfor));

18
plugins/libplugin-pay.c

@ -57,7 +57,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
p->route = NULL;
p->temp_exclusion = NULL;
p->failroute_retry = false;
p->bolt11 = NULL;
p->invstring = NULL;
p->routetxt = NULL;
p->max_htlcs = UINT32_MAX;
@ -82,6 +82,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
p->features = parent->features;
p->id = parent->id;
p->local_id = parent->local_id;
p->local_offer_id = parent->local_offer_id;
} else {
assert(cmd != NULL);
p->partid = 0;
@ -92,6 +93,7 @@ struct payment *payment_new(tal_t *ctx, struct command *cmd,
p->id = next_id++;
/* Caller must set this. */
p->local_id = NULL;
p->local_offer_id = NULL;
}
/* Initialize all modifier data so we can point to the fields when
@ -1443,12 +1445,16 @@ static struct command_result *payment_createonion_success(struct command *cmd,
if (p->label)
json_add_string(req->js, "label", p->label);
if (p->bolt11)
json_add_string(req->js, "bolt11", p->bolt11);
if (p->invstring)
/* FIXME: rename parameter to invstring */
json_add_string(req->js, "bolt11", p->invstring);
if (p->destination)
json_add_node_id(req->js, "destination", p->destination);
if (p->local_offer_id)
json_add_sha256(req->js, "local_offer_id", p->local_offer_id);
send_outreq(p->plugin, req);
return command_still_pending(cmd);
}
@ -1805,8 +1811,8 @@ static void payment_finished(struct payment *p)
json_add_string(ret, "failcodename",
failure->failcodename);
if (p->bolt11)
json_add_string(ret, "bolt11", p->bolt11);
if (p->invstring)
json_add_invstring(ret, p->invstring);
json_add_hex_talarr(ret, "raw_message",
result.failure->raw_message);
@ -3265,7 +3271,7 @@ static void presplit_cb(struct presplit_mod_data *d, struct payment *p)
/* Annotate the subpayments with the bolt11 string,
* they'll be used when aggregating the payments
* again. */
c->bolt11 = tal_strdup(c, p->bolt11);
c->invstring = tal_strdup(c, p->invstring);
/* Get ~ target, but don't exceed amt */
c->amount = fuzzed_near(target, amt);

8
plugins/libplugin-pay.h

@ -254,9 +254,13 @@ struct payment {
* true. Set only on the root payment. */
bool abort;
/* Serialized bolt11 string, kept attachd to the root so we can filter
/* Serialized bolt11/12 string, kept attachd to the root so we can filter
* by the invoice. */
const char *bolt11;
const char *invstring;
/* If this is paying a local offer, this is the one (sendpay ensures we
* don't pay twice for single-use offers) */
struct sha256 *local_offer_id;
/* Textual explanation of why this payment was attempted. */
const char *why;

80
plugins/pay.c

@ -67,8 +67,8 @@ struct pay_status {
struct amount_msat msat;
/* CLTV delay required by destination. */
u32 final_cltv;
/* Bolt11 invoice. */
const char *bolt11;
/* Bolt11/bolt12 invoice. */
const char *invstring;
/* What we did about routehints (if anything) */
const char *routehint_modifications;
@ -850,7 +850,7 @@ static struct command_result *getroute_done(struct command *cmd,
sendpay_done, sendpay_error, pc);
json_add_jsonstr(req->js, "route", attempt->route);
json_add_string(req->js, "payment_hash", pc->payment_hash);
json_add_string(req->js, "bolt11", pc->ps->bolt11);
json_add_string(req->js, "bolt11", pc->ps->invstring);
if (pc->label)
json_add_string(req->js, "label", pc->label);
if (pc->payment_secret)
@ -1255,7 +1255,7 @@ static struct route_info **filter_routehints(struct pay_command *pc,
}
static struct pay_status *add_pay_status(struct pay_command *pc,
const char *b11str)
const char *invstring STEALS)
{
struct pay_status *ps = tal(NULL, struct pay_status);
@ -1264,7 +1264,7 @@ static struct pay_status *add_pay_status(struct pay_command *pc,
ps->label = tal_steal(ps, pc->label);
ps->msat = pc->msat;
ps->final_cltv = pc->final_cltv;
ps->bolt11 = tal_steal(ps, b11str);
ps->invstring = tal_steal(ps, invstring);
ps->routehint_modifications = NULL;
ps->shadow = NULL;
ps->exclusions = NULL;
@ -1545,12 +1545,13 @@ static struct command_result *json_paystatus(struct command *cmd,
const jsmntok_t *params)
{
struct pay_status *ps;
const char *b11str;
const char *invstring;
struct json_stream *ret;
struct payment *p;
if (!param(cmd, buf, params,
p_opt("bolt11", param_string, &b11str),
/* FIXME: rename to invstring */
p_opt("bolt11", param_string, &invstring),
NULL))
return command_param_failed();
@ -1560,11 +1561,11 @@ static struct command_result *json_paystatus(struct command *cmd,
/* FIXME: Index by bolt11 string! */
/* TODO(cdecker) Remove once we migrated to `pay` with modifiers. */
list_for_each(&pay_status, ps, list) {
if (b11str && !streq(b11str, ps->bolt11))
if (invstring && !streq(invstring, ps->invstring))
continue;
json_object_start(ret, NULL);
json_add_string(ret, "bolt11", ps->bolt11);
json_add_invstring(ret, ps->invstring);
json_add_u64(ret, "msatoshi",
ps->msat.millisatoshis); /* Raw: JSON */
json_add_string(ret, "amount_msat",
@ -1591,15 +1592,15 @@ static struct command_result *json_paystatus(struct command *cmd,
list_for_each(&payments, p, list) {
assert(p->parent == NULL);
if (b11str && !streq(b11str, p->bolt11))
if (invstring && !streq(invstring, p->invstring))
continue;
json_object_start(ret, NULL);
if (p->label != NULL)
json_add_string(ret, "label", p->label);
if (p->bolt11)
json_add_string(ret, "bolt11", p->bolt11);
if (p->invstring)
json_add_invstring(ret, p->invstring);
json_add_amount_msat_only(ret, "amount_msat", p->amount);
json_add_string(
ret, "amount_msat",
@ -1654,8 +1655,8 @@ struct pay_mpp {
/* payment_hash from the invoice and lookup key */
const struct sha256 *payment_hash;
/* This is the bolt11 string */
const char *b11;
/* This is the bolt11/bolt12 string */
const char *invstring;
/* Status of combined payment */
const char *status;
/* Optional label (of first one!) */
@ -1698,7 +1699,7 @@ HTABLE_DEFINE_TYPE(struct pay_mpp, pay_mpp_key, pay_mpp_hash, pay_mpp_eq,
pay_map);
static void add_amount_sent(struct plugin *p,
const char *b11,
const char *invstring,
struct pay_mpp *mpp,
const char *buf,
const jsmntok_t *t)
@ -1711,7 +1712,7 @@ static void add_amount_sent(struct plugin *p,
if (!amount_msat_add(&mpp->amount_sent, mpp->amount_sent, sent))
plugin_log(p, LOG_BROKEN,
"Cannot add amount_sent_msat for %s: %s + %s",
b11,
invstring,
type_to_string(tmpctx, struct amount_msat, &mpp->amount_sent),
type_to_string(tmpctx, struct amount_msat, &sent));
@ -1734,7 +1735,7 @@ static void add_amount_sent(struct plugin *p,
if (!amount_msat_add(mpp->amount, *mpp->amount, recv))
plugin_log(p, LOG_BROKEN,
"Cannot add amount_msat for %s: %s + %s",
b11,
invstring,
type_to_string(tmpctx, struct amount_msat, mpp->amount),
type_to_string(tmpctx, struct amount_msat, &sent));
}
@ -1744,8 +1745,8 @@ static void add_new_entry(struct json_stream *ret,
const struct pay_mpp *pm)
{
json_object_start(ret, NULL);
if (pm->b11)
json_add_string(ret, "bolt11", pm->b11);
if (pm->invstring)
json_add_invstring(ret, pm->invstring);
if (pm->destination)
json_add_tok(ret, "destination", pm->destination, buf);
@ -1777,7 +1778,7 @@ static void add_new_entry(struct json_stream *ret,
static struct command_result *listsendpays_done(struct command *cmd,
const char *buf,
const jsmntok_t *result,
char *b11str)
char *invstring)
{
size_t i;
const jsmntok_t *t, *arr;
@ -1794,12 +1795,16 @@ static struct command_result *listsendpays_done(struct command *cmd,
"Unexpected non-array result from listsendpays");
json_for_each_arr(i, t, arr) {
const jsmntok_t *status, *b11tok, *hashtok, *createdtok;
const char *b11 = b11str;
const jsmntok_t *status, *invstrtok, *hashtok, *createdtok;
const char *invstr = invstring;
struct sha256 payment_hash;
u32 created_at;
b11tok = json_get_member(buf, t, "bolt11");
invstrtok = json_get_member(buf, t, "bolt11");
#if EXPERIMENTAL_FEATURES
if (!invstrtok)
invstrtok = json_get_member(buf, t, "bolt12");
#endif
hashtok = json_get_member(buf, t, "payment_hash");
createdtok = json_get_member(buf, t, "created_at");
assert(hashtok != NULL);
@ -1807,14 +1812,14 @@ static struct command_result *listsendpays_done(struct command *cmd,
json_to_sha256(buf, hashtok, &payment_hash);
json_to_u32(buf, createdtok, &created_at);
if (b11tok)
b11 = json_strdup(cmd, buf, b11tok);
if (invstrtok)
invstr = json_strdup(cmd, buf, invstrtok);
pm = pay_map_get(&pay_map, &payment_hash);
if (!pm) {
pm = tal(cmd, struct pay_mpp);
pm->payment_hash = tal_dup(pm, struct sha256, &payment_hash);
pm->b11 = tal_steal(pm, b11);
pm->invstring = tal_steal(pm, invstr);
pm->destination = json_get_member(buf, t, "destination");
pm->label = json_get_member(buf, t, "label");
pm->preimage = NULL;
@ -1828,13 +1833,13 @@ static struct command_result *listsendpays_done(struct command *cmd,
status = json_get_member(buf, t, "status");
if (json_tok_streq(buf, status, "complete")) {
add_amount_sent(cmd->plugin, pm->b11, pm, buf, t);
add_amount_sent(cmd->plugin, pm->invstring, pm, buf, t);
pm->num_nonfailed_parts++;
pm->status = "complete";
pm->preimage
= json_get_member(buf, t, "payment_preimage");
} else if (json_tok_streq(buf, status, "pending")) {
add_amount_sent(cmd->plugin, pm->b11, pm, buf, t);
add_amount_sent(cmd->plugin, pm->invstring, pm, buf, t);
pm->num_nonfailed_parts++;
/* Failed -> pending; don't downgrade success. */
if (!pm->status || !streq(pm->status, "complete"))
@ -1870,22 +1875,23 @@ static struct command_result *json_listpays(struct command *cmd,
const char *buf,
const jsmntok_t *params)
{
const char *b11str;
const char *invstring;
struct sha256 *payment_hash;
struct out_req *req;
/* FIXME: would be nice to parse as a bolt11 so check worked in future */
if (!param(cmd, buf, params,
p_opt("bolt11", param_string, &b11str),
/* FIXME: paramter should be invstring now */
p_opt("bolt11", param_string, &invstring),
p_opt("payment_hash", param_sha256, &payment_hash),
NULL))
return command_param_failed();
req = jsonrpc_request_start(cmd->plugin, cmd, "listsendpays",
listsendpays_done, forward_error,
cast_const(char *, b11str));
if (b11str)
json_add_string(req->js, "bolt11", b11str);
cast_const(char *, invstring));
if (invstring)
json_add_string(req->js, "bolt11", invstring);
if (payment_hash)
json_add_sha256(req->js, "payment_hash", payment_hash);
@ -1956,6 +1962,9 @@ static struct command_result *json_paymod(struct command *cmd,
unsigned int *retryfor;
u64 *riskfactor_millionths;
struct shadow_route_data *shadow_route;
#if EXPERIMENTAL_FEATURES
struct sha256 *local_offer_id;
#endif
#if DEVELOPER
bool *use_shadow;
#endif
@ -1974,6 +1983,9 @@ static struct command_result *json_paymod(struct command *cmd,
p_opt_def("maxdelay", param_number, &maxdelay,
maxdelay_default),
p_opt_def("exemptfee", param_msat, &exemptfee, AMOUNT_MSAT(5000)),
#if EXPERIMENTAL_FEATURES
p_opt("local_offer_id", param_sha256, &local_offer_id),
#endif
#if DEVELOPER
p_opt_def("use_shadow", param_bool, &use_shadow, true),
#endif
@ -2031,7 +2043,7 @@ static struct command_result *json_paymod(struct command *cmd,
p->routes = tal_steal(p, b11->routes);
p->min_final_cltv_expiry = b11->min_final_cltv_expiry;
p->features = tal_steal(p, b11->features);
p->bolt11 = tal_steal(p, b11str);
p->invstring = tal_steal(p, b11str);
p->why = "Initial attempt";
p->constraints.cltv_budget = *maxdelay;
p->deadline = timeabs_add(time_now(), time_from_sec(*retryfor));

2
tests/test_plugin.py

@ -387,6 +387,8 @@ def test_pay_plugin(node_factory):
# Make sure usage messages are present.
msg = 'pay bolt11 [msatoshi] [label] [riskfactor] [maxfeepercent] '\
'[retry_for] [maxdelay] [exemptfee]'
if EXPERIMENTAL_FEATURES:
msg += ' [local_offer_id]'
if DEVELOPER:
msg += ' [use_shadow]'
assert only_one(l1.rpc.help('pay')['help'])['command'] == msg

2
wallet/db_postgres_sqlgen.c

@ -1762,4 +1762,4 @@ struct db_query db_postgres_queries[] = {
#endif /* LIGHTNINGD_WALLET_GEN_DB_POSTGRES */
// SHA256STAMP:93d29f78f9f38cc779f4fbea480b90ce38899ff1c2f534e4160b2bf8a05b57ee
// SHA256STAMP:774d5116e102d98351730072b4aa0b48d27b05c364680fc406f8b12bf4c7e293

2
wallet/db_sqlite3_sqlgen.c

@ -1762,4 +1762,4 @@ struct db_query db_sqlite3_queries[] = {
#endif /* LIGHTNINGD_WALLET_GEN_DB_SQLITE3 */
// SHA256STAMP:93d29f78f9f38cc779f4fbea480b90ce38899ff1c2f534e4160b2bf8a05b57ee
// SHA256STAMP:774d5116e102d98351730072b4aa0b48d27b05c364680fc406f8b12bf4c7e293

2
wallet/statements_gettextgen.po

@ -1161,4 +1161,4 @@ msgstr ""
#: wallet/test/run-wallet.c:1378
msgid "INSERT INTO channels (id) VALUES (1);"
msgstr ""
# SHA256STAMP:f567e217e4f94d8fd86c0c8d6997931d891df4f8295517fa527b80a323b256a8
# SHA256STAMP:50622dd1a8b0f2fe71efa1c1d175f7ad130f3042db84e0c9547f849a328e8f5d

8
wallet/wallet.c

@ -2530,8 +2530,8 @@ void wallet_payment_store(struct wallet *wallet,
else
db_bind_null(stmt, 9);
if (payment->bolt11 != NULL)
db_bind_text(stmt, 10, payment->bolt11);
if (payment->invstring != NULL)
db_bind_text(stmt, 10, payment->invstring);
else
db_bind_null(stmt, 10);
@ -2641,10 +2641,10 @@ static struct wallet_payment *wallet_stmt2payment(const tal_t *ctx,
payment->label = NULL;
if (!db_column_is_null(stmt, 12) && db_column_text(stmt, 12) != NULL)
payment->bolt11 = tal_strdup(
payment->invstring = tal_strdup(
payment, (const char *)db_column_text(stmt, 12));
else
payment->bolt11 = NULL;
payment->invstring = NULL;
if (!db_column_is_null(stmt, 13))
payment->failonion =

4
wallet/wallet.h

@ -236,8 +236,8 @@ struct wallet_payment {
struct secret *path_secrets;
struct node_id *route_nodes;
struct short_channel_id *route_channels;
/* bolt11 string; NULL for old payments. */
const char *bolt11;
/* bolt11/bolt12 string; NULL for old payments. */
const char *invstring;
/* The label of the payment. Must support `tal_len` */
const char *label;

Loading…
Cancel
Save