Skip to content

Commit

Permalink
common/bolt11: use struct amount_msat
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Feb 21, 2019
1 parent 28ec65f commit 3ba544b
Show file tree
Hide file tree
Showing 14 changed files with 77 additions and 52 deletions.
26 changes: 14 additions & 12 deletions common/bolt11.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 4 additions & 2 deletions common/bolt11.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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,
Expand Down
15 changes: 8 additions & 7 deletions common/test/run-bolt11.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include "../amount.c"
#include "../bech32.c"
#include "../bech32_util.c"
#include "../bolt11.c"
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions devtools/bolt11-cli.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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)
Expand Down
17 changes: 7 additions & 10 deletions lightningd/invoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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,
Expand Down Expand Up @@ -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)" : "");

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion lightningd/json.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
12 changes: 10 additions & 2 deletions lightningd/test/run-invoice-select-inchan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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, ...)
Expand Down Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions plugins/pay.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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,
Expand Down
7 changes: 7 additions & 0 deletions tests/test_pay.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
15 changes: 8 additions & 7 deletions wallet/invoices.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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;
Expand Down
Loading

0 comments on commit 3ba544b

Please sign in to comment.