From 7ad8fde0607c1ad7783ca422a57de7f5a348bab6 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 20 Aug 2020 16:21:03 +0930 Subject: [PATCH] bolt11: update ctlv expiry, always write it. As per https://github.com/lightningnetwork/lightning-rfc/pull/785 Signed-off-by: Rusty Russell Changelog-Changed: protocol: bolt11 invoices always include CLTV fields (see lightning-rfc#785) --- Makefile | 2 +- common/bolt11.c | 17 +++++++++++------ common/test/run-bolt11.c | 8 ++++++-- tests/test_invoices.py | 2 +- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Makefile b/Makefile index fc7b0fa21..439cca863 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ CCANDIR := ccan # Where we keep the BOLT RFCs BOLTDIR := ../lightning-rfc/ -BOLTVERSION := 886bf7a430db706b483b7b02d64a82bf175c0b46 +BOLTVERSION := b4132ff24025742ad8e175d52b68380520e9f0b7 -include config.vars diff --git a/common/bolt11.c b/common/bolt11.c index f6aa4689b..b69d875a3 100644 --- a/common/bolt11.c +++ b/common/bolt11.c @@ -248,9 +248,8 @@ static char *decode_x(struct bolt11 *b11, /* BOLT #11: * * `c` (24): `data_length` variable. `min_final_cltv_expiry` to use for the - * last HTLC in the route. Default is 9 if not specified. + * last HTLC in the route. Default is 18 if not specified. */ -#define DEFAULT_C 9 static char *decode_c(struct bolt11 *b11, struct hash_u5 *hu5, u5 **data, size_t *data_len, @@ -536,7 +535,11 @@ struct bolt11 *new_bolt11(const tal_t *ctx, b11->msat = NULL; b11->expiry = DEFAULT_X; b11->features = tal_arr(b11, u8, 0); - b11->min_final_cltv_expiry = DEFAULT_C; + /* BOLT #11: + * - if the `c` field (`min_final_cltv_expiry`) is not provided: + * - MUST use an expiry delta of at least 18 when making the payment + */ + b11->min_final_cltv_expiry = 18; b11->payment_secret = NULL; if (msat) @@ -861,8 +864,8 @@ static void push_field(u5 **data, char type, const void *src, size_t nbits) * * - if `x` is included: * - SHOULD use the minimum `data_length` possible. + * - MUST include one `c` field (`min_final_cltv_expiry`). *... - * - if `c` is included: * - SHOULD use the minimum `data_length` possible. */ static void push_varlen_field(u5 **data, char type, u64 val) @@ -1095,8 +1098,10 @@ char *bolt11_encode_(const tal_t *ctx, if (b11->expiry != DEFAULT_X) encode_x(&data, b11->expiry); - if (b11->min_final_cltv_expiry != DEFAULT_C) - encode_c(&data, b11->min_final_cltv_expiry); + /* BOLT #11: + * - MUST include one `c` field (`min_final_cltv_expiry`). + */ + encode_c(&data, b11->min_final_cltv_expiry); if (b11->payment_secret) encode_s(&data, b11->payment_secret); diff --git a/common/test/run-bolt11.c b/common/test/run-bolt11.c index 9b2258e4a..d8085b90a 100644 --- a/common/test/run-bolt11.c +++ b/common/test/run-bolt11.c @@ -119,6 +119,10 @@ static void test_b11(const char *b11str, } assert(!expect_extra); + /* FIXME: Spec changed to require c fields, but test vectors don't! */ + if (b11->min_final_cltv_expiry == 18) + return; + /* Re-encode to check */ reproduce = bolt11_encode(tmpctx, b11, false, test_sign, NULL); for (size_t i = 0; i < strlen(reproduce); i++) { @@ -294,7 +298,7 @@ int main(void) strlen("850aeaf5f69670e8889936fc2e0cff3ceb0c3b5eab8f04ae57767118db673a91"), &b11->payment_hash, sizeof(b11->payment_hash))) abort(); - b11->min_final_cltv_expiry = 9; + b11->min_final_cltv_expiry = 18; b11->receiver_id = node; b11->description = "Payment request with multipart support"; b11->expiry = 28800; @@ -454,7 +458,7 @@ int main(void) /* This one can be encoded, but not decoded */ set_feature_bit(&b11->features, 100); badstr = bolt11_encode(tmpctx, b11, false, test_sign, NULL); - assert(streq(badstr, "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeessp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqpqsqq40wa3khl49yue3zsgm26jrepqr2eghqlx86rttutve3ugd05em86nsefzh4pfurpd9ek9w2vp95zxqnfe2u7ckudyahsa52q66tgzcp6t2dyk")); + assert(streq(badstr, "lnbc25m1pvjluezpp5qqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqqqsyqcyq5rqwzqfqypqdq5vdhkven9v5sxyetpdeescqpjsp5zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zyg3zygs9q4psqqqqqqqqqqqqqqqpqsq0hxcz4sktfhmyqsedyuf79vyhah4kv3ruth2hrpvd8tnsceqwj592r4a6w5x2vh5cr4jadanl6qu8lqs8ggxr0pax8mdlwjm2hyyg7gpe7cxue")); /* Empty set of allowed bits, ensures this fails! */ fset = tal(tmpctx, struct feature_set); fset->bits[BOLT11_FEATURE] = tal_arr(fset, u8, 0); diff --git a/tests/test_invoices.py b/tests/test_invoices.py index ef0ac1241..83809e7dc 100644 --- a/tests/test_invoices.py +++ b/tests/test_invoices.py @@ -584,7 +584,7 @@ def test_decode_unknown(node_factory): assert b11['description'] == 'Payment request with multipart support' assert b11['expiry'] == 28800 assert b11['payee'] == '02330d13587b67a85c0a36ea001c4dba14bcd48dda8988f7303275b040bffb6abd' - assert b11['min_final_cltv_expiry'] == 9 + assert b11['min_final_cltv_expiry'] == 18 extra = only_one(b11['extra']) assert extra['tag'] == 'v' assert extra['data'] == 'dp68gup69uhnzwfj9cejuvf3xshrwde68qcrswf0d46kcarfwpshyaplw3skw0tdw4k8g6tsv9e8g'