From d38cfcf33bdf1408b5d05b746c4c32172a94b3d3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 21 Jul 2021 15:08:25 +0930 Subject: [PATCH] lightningd: don't assume zero-length tlv fields will be NULL. 1. We assumed an empty upfront_shutdown_script TLV would become NULL: RPC call failed: method: fundchannel, payload: {'id': '022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59', 'amount': 1000000, 'announce': True}, error: {'code': -1, 'message': 'They sent error channel e7c2d5d14462fe269631418fbfc3db327843382e6a2a5a9c2991d2d6ba31d9f5: Unacceptable upfront_shutdown_script ', 'data': {'id': '022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59', 'method': 'fundchannel_start'}}" 2. We were assuming an empty enctlv would become NULL, too. We should not have done this (there's a semantic difference between "empty" and not-present for TLVs), so prepare for the change. Signed-off-by: Rusty Russell --- lightningd/onion_message.c | 2 +- openingd/openingd.c | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lightningd/onion_message.c b/lightningd/onion_message.c index 63269c441..1851b9509 100644 --- a/lightningd/onion_message.c +++ b/lightningd/onion_message.c @@ -28,7 +28,7 @@ static void onion_message_serialize(struct onion_message_hook_payload *payload, json_object_start(stream, NULL); json_add_pubkey(stream, "id", &payload->reply_path[i]->node_id); - if (payload->reply_path[i]->enctlv) + if (tal_bytelen(payload->reply_path[i]->enctlv) != 0) json_add_hex_talarr(stream, "enctlv", payload->reply_path[i]->enctlv); if (i == 0) diff --git a/openingd/openingd.c b/openingd/openingd.c index 113210d8c..d12850fd2 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -329,6 +329,16 @@ static void set_remote_upfront_shutdown(struct state *state, state->their_features, OPT_SHUTDOWN_ANYSEGWIT); + /* BOLT #2: + * + * - MUST include `upfront_shutdown_script` with either a valid + * `shutdown_scriptpubkey` as required by `shutdown` `scriptpubkey`, + * or a zero-length `shutdown_scriptpubkey` (ie. `0x0000`). + */ + /* We turn empty into NULL. */ + if (tal_bytelen(shutdown_scriptpubkey) == 0) + shutdown_scriptpubkey = tal_free(shutdown_scriptpubkey); + state->upfront_shutdown_script[REMOTE] = tal_steal(state, shutdown_scriptpubkey);