common/bolt11: use struct amount_msat

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2019-02-21 13:08:35 +10:30
parent 28ec65fd79
commit 3ba544bfde
14 changed files with 77 additions and 52 deletions

View File

@ -433,7 +433,8 @@ static char *decode_r(struct bolt11 *b11,
return NULL;
}
struct bolt11 *new_bolt11(const tal_t *ctx, u64 *msatoshi)
struct bolt11 *new_bolt11(const tal_t *ctx,
const struct amount_msat *msat TAKES)
{
struct bolt11 *b11 = tal(ctx, struct bolt11);
@ -442,12 +443,12 @@ struct bolt11 *new_bolt11(const tal_t *ctx, u64 *msatoshi)
b11->description_hash = NULL;
b11->fallbacks = NULL;
b11->routes = NULL;
b11->msatoshi = NULL;
b11->msat = NULL;
b11->expiry = DEFAULT_X;
b11->min_final_cltv_expiry = DEFAULT_C;
if (msatoshi)
b11->msatoshi = tal_dup(b11, u64, msatoshi);
if (msat)
b11->msat = tal_dup(b11, struct amount_msat, msat);
return b11;
}
@ -520,7 +521,7 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
*
* - SHOULD indicate to the payer that amount is unspecified.
*/
b11->msatoshi = NULL;
b11->msat = NULL;
} else {
u64 m10 = 10;
u64 amount;
@ -556,8 +557,8 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
* `amount` by the `multiplier` value to derive the
* amount required for payment.
*/
b11->msatoshi = tal(b11, u64);
*b11->msatoshi = amount * m10 / 10;
b11->msat = tal(b11, struct amount_msat);
b11->msat->millisatoshis = amount * m10 / 10;
}
/* BOLT #11:
@ -886,19 +887,20 @@ char *bolt11_encode_(const tal_t *ctx,
* - MUST encode `amount` as a positive decimal integer with no leading 0s.
* - SHOULD use the shortest representation possible, by using the largest multiplier or omitting the multiplier.
*/
if (b11->msatoshi) {
if (b11->msat) {
char postfix;
if (*b11->msatoshi % MSAT_PER_BTC == 0) {
u64 msat = b11->msat->millisatoshis;
if (msat % MSAT_PER_BTC == 0) {
postfix = '\0';
amount = *b11->msatoshi / MSAT_PER_BTC;
amount = msat / MSAT_PER_BTC;
} else {
size_t i;
for (i = 0; i < ARRAY_SIZE(multipliers)-1; i++) {
if (!(*b11->msatoshi * 10 % multipliers[i].m10))
if (!(msat * 10 % multipliers[i].m10))
break;
}
postfix = multipliers[i].letter;
amount = *b11->msatoshi * 10 / multipliers[i].m10;
amount = msat * 10 / multipliers[i].m10;
}
hrp = tal_fmt(tmpctx, "ln%s%"PRIu64"%c",
b11->chain->bip173_name, amount, postfix);

View File

@ -6,6 +6,7 @@
#include <bitcoin/short_channel_id.h>
#include <ccan/list/list.h>
#include <ccan/short_types/short_types.h>
#include <ccan/take/take.h>
#include <common/hash_u5.h>
#include <secp256k1_recovery.h>
@ -37,7 +38,7 @@ struct route_info {
struct bolt11 {
const struct chainparams *chain;
u64 timestamp;
u64 *msatoshi; /* NULL if not specified. */
struct amount_msat *msat; /* NULL if not specified. */
struct sha256 payment_hash;
struct pubkey receiver_id;
@ -70,7 +71,8 @@ struct bolt11 *bolt11_decode(const tal_t *ctx, const char *str,
const char *description, char **fail);
/* Initialize an empty bolt11 struct with optional amount */
struct bolt11 *new_bolt11(const tal_t *ctx, u64 *msatoshi);
struct bolt11 *new_bolt11(const tal_t *ctx,
const struct amount_msat *msat TAKES);
/* Encodes and signs, even if it's nonsense. */
char *bolt11_encode_(const tal_t *ctx,

View File

@ -1,3 +1,4 @@
#include "../amount.c"
#include "../bech32.c"
#include "../bech32_util.c"
#include "../bolt11.c"
@ -79,10 +80,10 @@ static void test_b11(const char *b11str,
assert(b11->chain == expect_b11->chain);
assert(b11->timestamp == expect_b11->timestamp);
if (!b11->msatoshi)
assert(!expect_b11->msatoshi);
if (!b11->msat)
assert(!expect_b11->msat);
else
assert(*b11->msatoshi == *expect_b11->msatoshi);
assert(amount_msat_eq(*b11->msat, *expect_b11->msat));
assert(sha256_eq(&b11->payment_hash, &expect_b11->payment_hash));
if (!b11->description)
assert(!expect_b11->description);
@ -120,7 +121,7 @@ int main(void)
struct bolt11 *b11;
struct pubkey node;
u64 msatoshi;
struct amount_msat msatoshi;
const char *badstr;
wally_init(0);
@ -195,7 +196,7 @@ int main(void)
* * `aztrnwngzn3kdzw5hydlzf03qdgm2hdq27cqv3agm2awhz5se903vruatfhq77w3ls4evs3ch9zw97j25emudupq63nyw24cg27h2rsp`: signature
* * `fj9srp`: Bech32 checksum
*/
msatoshi = 2500 * (1000ULL * 100000000) / 1000000;
msatoshi = AMOUNT_MSAT(2500 * (1000ULL * 100000000) / 1000000);
b11 = new_bolt11(tmpctx, &msatoshi);
b11->chain = chainparams_for_network("bitcoin");
b11->timestamp = 1496314658;
@ -227,7 +228,7 @@ int main(void)
* * `cc6gd6ql3jrc5yzme8v4ntcewwz5cnw92tz0pc8qcuufvq7khhr8wpald05e92xw006sq94mg8v2ndf4sefvf9sygkshp5zfem29trqq`: signature
* * `2yxxz7`: Bech32 checksum
*/
msatoshi = 20 * (1000ULL * 100000000) / 1000;
msatoshi = AMOUNT_MSAT(20 * (1000ULL * 100000000) / 1000);
b11 = new_bolt11(tmpctx, &msatoshi);
b11->chain = chainparams_for_network("bitcoin");
b11->timestamp = 1496314658;
@ -252,7 +253,7 @@ int main(void)
}
/* ALL UPPERCASE is allowed (useful for QR codes) */
msatoshi = 2500 * (1000ULL * 100000000) / 1000000;
msatoshi = AMOUNT_MSAT(2500 * (1000ULL * 100000000) / 1000000);
b11 = new_bolt11(tmpctx, &msatoshi);
b11->chain = chainparams_for_network("bitcoin");
b11->timestamp = 1496314658;

View File

@ -8,6 +8,7 @@
#include <ccan/str/str.h>
#include <ccan/tal/str/str.h>
#include <ccan/time/time.h>
#include <common/amount.h>
#include <common/bech32.h>
#include <common/bolt11.h>
#include <common/type_to_string.h>
@ -104,8 +105,11 @@ int main(int argc, char *argv[])
printf("payment_hash: %s\n",
tal_hexstr(ctx, &b11->payment_hash, sizeof(b11->payment_hash)));
printf("min_final_cltv_expiry: %u\n", b11->min_final_cltv_expiry);
if (b11->msatoshi)
printf("msatoshi: %"PRIu64"\n", *b11->msatoshi);
if (b11->msat) {
printf("msatoshi: %"PRIu64"\n", b11->msat->millisatoshis);
printf("amount_msat: %s\n",
type_to_string(tmpctx, struct amount_msat, b11->msat));
}
if (b11->description)
printf("description: '%s'\n", b11->description);
if (b11->description_hash)

View File

@ -236,7 +236,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
info->b11->routes
= select_inchan(info->b11,
info->cmd->ld,
info->b11->msatoshi ? *info->b11->msatoshi : 1,
info->b11->msat ? info->b11->msat->millisatoshis : 1,
inchans,
&any_offline);
@ -255,7 +255,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
if (!wallet_invoice_create(wallet,
&invoice,
info->b11->msatoshi,
info->b11->msat,
info->label,
info->b11->expiry,
b11enc,
@ -283,7 +283,7 @@ static void gossipd_incoming_channels_reply(struct subd *gossipd,
log_unusual(info->cmd->ld->log,
"invoice: insufficient incoming capacity for %"PRIu64
" msatoshis%s",
info->b11->msatoshi ? *info->b11->msatoshi : 0,
info->b11->msat ? info->b11->msat->millisatoshis : 0,
any_offline
? " (among currently connected peers)" : "");
@ -469,11 +469,7 @@ static struct command_result *json_invoice(struct command *cmd,
/* Generate preimage hash. */
sha256(&rhash, &info->payment_preimage, sizeof(info->payment_preimage));
/* FIXME: Make bolt11 take struct amount_msat */
if (msatoshi_val)
info->b11 = new_bolt11(info, &msatoshi_val->millisatoshis);
else
info->b11 = new_bolt11(info, NULL);
info->b11 = new_bolt11(info, msatoshi_val);
info->b11->chain = chainparams;
info->b11->timestamp = time_now().ts.tv_sec;
info->b11->payment_hash = rhash;
@ -806,8 +802,9 @@ static struct command_result *json_decodepay(struct command *cmd,
json_add_u64(response, "created_at", b11->timestamp);
json_add_u64(response, "expiry", b11->expiry);
json_add_pubkey(response, "payee", &b11->receiver_id);
if (b11->msatoshi)
json_add_u64(response, "msatoshi", *b11->msatoshi);
if (b11->msat)
json_add_amount_msat(response, *b11->msat,
"msatoshi", "amount_msat");
if (b11->description) {
struct json_escaped *esc = json_escape(NULL, b11->description);
json_add_escaped_string(response, "description", take(esc));

View File

@ -286,7 +286,7 @@ void json_add_literal(struct json_stream *result, const char *fieldname,
json_add_member(result, fieldname, "%.*s", len, literal);
}
void json_add_string(struct json_stream *result, const char *fieldname, const char *value)
void json_add_string(struct json_stream *result, const char *fieldname, const char *value TAKES)
{
struct json_escaped *esc = json_partial_escape(NULL, value);

View File

@ -120,6 +120,13 @@ void json_add_address_internal(struct json_stream *response UNNEEDED,
const char *fieldname UNNEEDED,
const struct wireaddr_internal *addr UNNEEDED)
{ fprintf(stderr, "json_add_address_internal called!\n"); abort(); }
/* Generated stub for json_add_amount_msat */
void json_add_amount_msat(struct json_stream *result UNNEEDED,
struct amount_msat msat UNNEEDED,
const char *rawfieldname UNNEEDED,
const char *msatfieldname)
{ fprintf(stderr, "json_add_amount_msat called!\n"); abort(); }
/* Generated stub for json_add_bool */
void json_add_bool(struct json_stream *result UNNEEDED, const char *fieldname UNNEEDED,
bool value UNNEEDED)
@ -229,7 +236,8 @@ void log_io(struct log *log UNNEEDED, enum log_level dir UNNEEDED, const char *c
const void *data UNNEEDED, size_t len UNNEEDED)
{ fprintf(stderr, "log_io called!\n"); abort(); }
/* Generated stub for new_bolt11 */
struct bolt11 *new_bolt11(const tal_t *ctx UNNEEDED, u64 *msatoshi UNNEEDED)
struct bolt11 *new_bolt11(const tal_t *ctx UNNEEDED,
const struct amount_msat *msat TAKES UNNEEDED)
{ fprintf(stderr, "new_bolt11 called!\n"); abort(); }
/* Generated stub for new_log */
struct log *new_log(const tal_t *ctx UNNEEDED, struct log_book *record UNNEEDED, const char *fmt UNNEEDED, ...)
@ -454,7 +462,7 @@ void wallet_invoice_autoclean(struct wallet * wallet UNNEEDED,
/* Generated stub for wallet_invoice_create */
bool wallet_invoice_create(struct wallet *wallet UNNEEDED,
struct invoice *pinvoice UNNEEDED,
u64 *msatoshi TAKES UNNEEDED,
const struct amount_msat *msat TAKES UNNEEDED,
const struct json_escaped *label TAKES UNNEEDED,
u64 expiry UNNEEDED,
const char *b11enc UNNEEDED,

View File

@ -2,6 +2,7 @@
#include <ccan/intmap/intmap.h>
#include <ccan/tal/str/str.h>
#include <ccan/time/time.h>
#include <common/amount.h>
#include <common/bolt11.h>
#include <common/pseudorand.h>
#include <common/type_to_string.h>
@ -852,12 +853,12 @@ static struct command_result *handle_pay(struct command *cmd,
return command_fail(cmd, PAY_INVOICE_EXPIRED, "Invoice expired");
}
if (b11->msatoshi) {
if (b11->msat) {
if (msatoshi) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,
"msatoshi parameter unnecessary");
}
pc->msatoshi = *b11->msatoshi;
pc->msatoshi = b11->msat->millisatoshis;
} else {
if (!msatoshi) {
return command_fail(cmd, JSONRPC2_INVALID_PARAMS,

View File

@ -573,6 +573,7 @@ def test_decodepay(node_factory):
)
assert b11['currency'] == 'bc'
assert b11['msatoshi'] == 2500 * 10**11 // 1000000
assert b11['amount_msat'] == str(2500 * 10**11 // 1000000) + 'msat'
assert b11['created_at'] == 1496314658
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['description'] == '1 cup coffee'
@ -606,6 +607,7 @@ def test_decodepay(node_factory):
)
assert b11['currency'] == 'bc'
assert b11['msatoshi'] == 20 * 10**11 // 1000
assert b11['amount_msat'] == str(20 * 10**11 // 1000) + 'msat'
assert b11['created_at'] == 1496314658
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
@ -638,6 +640,7 @@ def test_decodepay(node_factory):
)
assert b11['currency'] == 'tb'
assert b11['msatoshi'] == 20 * 10**11 // 1000
assert b11['amount_msat'] == str(20 * 10**11 // 1000) + 'msat'
assert b11['created_at'] == 1496314658
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
@ -669,6 +672,7 @@ def test_decodepay(node_factory):
b11 = l1.rpc.decodepay('lnbc20m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqsfpp3qjmp7lwpagxun9pygexvgpjdc4jdj85fr9yq20q82gphp2nflc7jtzrcazrra7wwgzxqc8u7754cdlpfrmccae92qgzqvzq2ps8pqqqqqqpqqqqq9qqqvpeuqafqxu92d8lr6fvg0r5gv0heeeqgcrqlnm6jhphu9y00rrhy4grqszsvpcgpy9qqqqqqgqqqqq7qqzqj9n4evl6mr5aj9f58zp6fyjzup6ywn3x6sk8akg5v4tgn2q8g4fhx05wf6juaxu9760yp46454gpg5mtzgerlzezqcqvjnhjh8z3g2qqdhhwkj', 'One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon')
assert b11['currency'] == 'bc'
assert b11['msatoshi'] == 20 * 10**11 // 1000
assert b11['amount_msat'] == str(20 * 10**11 // 1000) + 'msat'
assert b11['created_at'] == 1496314658
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
@ -711,6 +715,7 @@ def test_decodepay(node_factory):
b11 = l1.rpc.decodepay('lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppj3a24vwu6r8ejrss3axul8rxldph2q7z9kmrgvr7xlaqm47apw3d48zm203kzcq357a4ls9al2ea73r8jcceyjtya6fu5wzzpe50zrge6ulk4nvjcpxlekvmxl6qcs9j3tz0469gq5g658y', 'One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon')
assert b11['currency'] == 'bc'
assert b11['msatoshi'] == 20 * 10**11 // 1000
assert b11['amount_msat'] == str(20 * 10**11 // 1000) + 'msat'
assert b11['created_at'] == 1496314658
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
@ -737,6 +742,7 @@ def test_decodepay(node_factory):
b11 = l1.rpc.decodepay('lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfppqw508d6qejxtdg4y5r3zarvary0c5xw7kepvrhrm9s57hejg0p662ur5j5cr03890fa7k2pypgttmh4897d3raaq85a293e9jpuqwl0rnfuwzam7yr8e690nd2ypcq9hlkdwdvycqa0qza8', 'One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon')
assert b11['currency'] == 'bc'
assert b11['msatoshi'] == 20 * 10**11 // 1000
assert b11['amount_msat'] == str(20 * 10**11 // 1000) + 'msat'
assert b11['created_at'] == 1496314658
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600
@ -763,6 +769,7 @@ def test_decodepay(node_factory):
b11 = l1.rpc.decodepay('lnbc20m1pvjluezhp58yjmdan79s6qqdhdzgynm4zwqd5d7xmw5fk98klysy043l2ahrqspp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqfp4qrp33g0q5c5txsp9arysrx4k6zdkfs4nce4xj0gdcccefvpysxf3q28j0v3rwgy9pvjnd48ee2pl8xrpxysd5g44td63g6xcjcu003j3qe8878hluqlvl3km8rm92f5stamd3jw763n3hck0ct7p8wwj463cql26ava', 'One piece of chocolate cake, one icecream cone, one pickle, one slice of swiss cheese, one slice of salami, one lollypop, one piece of cherry pie, one sausage, one cupcake, and one slice of watermelon')
assert b11['currency'] == 'bc'
assert b11['msatoshi'] == 20 * 10**11 // 1000
assert b11['amount_msat'] == str(20 * 10**11 // 1000) + 'msat'
assert b11['created_at'] == 1496314658
assert b11['payment_hash'] == '0001020304050607080900010203040506070809000102030405060708090102'
assert b11['expiry'] == 3600

View File

@ -6,6 +6,7 @@
#include <ccan/tal/str/str.h>
#include <ccan/time/time.h>
#include <ccan/timer/timer.h>
#include <common/amount.h>
#include <common/timeout.h>
#include <common/utils.h>
#include <lightningd/invoice.h>
@ -259,7 +260,7 @@ static void install_expiration_timer(struct invoices *invoices)
bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice,
u64 *msatoshi TAKES,
const struct amount_msat *msat TAKES,
const struct json_escaped *label TAKES,
u64 expiry,
const char *b11enc,
@ -273,8 +274,8 @@ bool invoices_create(struct invoices *invoices,
u64 now = time_now().ts.tv_sec;
if (invoices_find_by_label(invoices, &dummy, label)) {
if (taken(msatoshi))
tal_free(msatoshi);
if (taken(msat))
tal_free(msat);
if (taken(label))
tal_free(label);
return false;
@ -301,8 +302,8 @@ bool invoices_create(struct invoices *invoices,
sqlite3_bind_blob(stmt, 1, rhash, sizeof(struct sha256), SQLITE_TRANSIENT);
sqlite3_bind_blob(stmt, 2, r, sizeof(struct preimage), SQLITE_TRANSIENT);
sqlite3_bind_int(stmt, 3, UNPAID);
if (msatoshi)
sqlite3_bind_int64(stmt, 4, *msatoshi);
if (msat)
sqlite3_bind_int64(stmt, 4, msat->millisatoshis);
else
sqlite3_bind_null(stmt, 4);
sqlite3_bind_json_escaped(stmt, 5, label);
@ -322,8 +323,8 @@ bool invoices_create(struct invoices *invoices,
install_expiration_timer(invoices);
}
if (taken(msatoshi))
tal_free(msatoshi);
if (taken(msat))
tal_free(msat);
if (taken(label))
tal_free(label);
return true;

View File

@ -6,6 +6,7 @@
#include <ccan/take/take.h>
#include <ccan/tal/tal.h>
struct amount_msat;
struct db;
struct json_escaped;
struct invoice;
@ -34,7 +35,7 @@ struct invoices *invoices_new(const tal_t *ctx,
*
* @invoices - the invoice handler.
* @pinvoice - pointer to location to load new invoice in.
* @msatoshi - the amount the invoice should have, or
* @msat - the amount the invoice should have, or
* NULL for any-amount invoices.
* @label - the unique label for this invoice. Must be
* non-NULL.
@ -47,7 +48,7 @@ struct invoices *invoices_new(const tal_t *ctx,
*/
bool invoices_create(struct invoices *invoices,
struct invoice *pinvoice,
u64 *msatoshi TAKES,
const struct amount_msat *msat TAKES,
const struct json_escaped *label TAKES,
u64 expiry,
const char *b11enc,

View File

@ -120,7 +120,7 @@ void invoices_autoclean_set(struct invoices *invoices UNNEEDED,
/* Generated stub for invoices_create */
bool invoices_create(struct invoices *invoices UNNEEDED,
struct invoice *pinvoice UNNEEDED,
u64 *msatoshi TAKES UNNEEDED,
const struct amount_msat *msat TAKES UNNEEDED,
const struct json_escaped *label TAKES UNNEEDED,
u64 expiry UNNEEDED,
const char *b11enc UNNEEDED,

View File

@ -1473,7 +1473,7 @@ bool wallet_htlcs_load_for_channel(struct wallet *wallet,
bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice,
u64 *msatoshi TAKES,
const struct amount_msat *msat TAKES,
const struct json_escaped *label TAKES,
u64 expiry,
const char *b11enc,
@ -1481,7 +1481,7 @@ bool wallet_invoice_create(struct wallet *wallet,
const struct preimage *r,
const struct sha256 *rhash)
{
return invoices_create(wallet->invoices, pinvoice, msatoshi, label, expiry, b11enc, description, r, rhash);
return invoices_create(wallet->invoices, pinvoice, msat, label, expiry, b11enc, description, r, rhash);
}
bool wallet_invoice_find_by_label(struct wallet *wallet,
struct invoice *pinvoice,

View File

@ -19,6 +19,7 @@
#include <wally_bip32.h>
enum onion_type;
struct amount_msat;
struct invoices;
struct channel;
struct lightningd;
@ -611,7 +612,7 @@ struct invoice {
*
* @wallet - the wallet to create the invoice in.
* @pinvoice - pointer to location to load new invoice in.
* @msatoshi - the amount the invoice should have, or
* @msat - the amount the invoice should have, or
* NULL for any-amount invoices.
* @label - the unique label for this invoice. Must be
* non-NULL.
@ -624,7 +625,7 @@ struct invoice {
*/
bool wallet_invoice_create(struct wallet *wallet,
struct invoice *pinvoice,
u64 *msatoshi TAKES,
const struct amount_msat *msat TAKES,
const struct json_escaped *label TAKES,
u64 expiry,
const char *b11enc,