From 2003a1b8e43716ed7c575b631a704c25cc87da0e Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:25:31 +0930 Subject: [PATCH 01/20] test: fix tlvs test in funding_locked tlv. This FIXME caught my eye, as it's wrong: TLVs are canonical, so they cannot differ in bits and be equal. The equality function needs to be written correctly, however, otherwise it will crash! Signed-off-by: Rusty Russell --- wire/test/run-peer-wire.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/wire/test/run-peer-wire.c b/wire/test/run-peer-wire.c index e8de0a6adb7a..173032973486 100644 --- a/wire/test/run-peer-wire.c +++ b/wire/test/run-peer-wire.c @@ -811,9 +811,25 @@ static bool channel_announcement_eq(const struct msg_channel_announcement *a, static bool funding_locked_eq(const struct msg_funding_locked *a, const struct msg_funding_locked *b) { - return eq_upto(a, b, tlvs) && - memeq(a->tlvs->alias, sizeof(a->tlvs->alias), b->tlvs->alias, - sizeof(b->tlvs->alias)); + if (!eq_upto(a, b, tlvs)) + return false; + + /* Both or neither */ + if (!a->tlvs != !b->tlvs) + return false; + + if (!a->tlvs) + return true; + + /* Both or neither */ + if (!a->tlvs->alias != !b->tlvs->alias) + return false; + + if (!a->tlvs->alias) + return true; + + return memeq(a->tlvs->alias, sizeof(a->tlvs->alias), + b->tlvs->alias, sizeof(b->tlvs->alias)); } static bool announcement_signatures_eq(const struct msg_announcement_signatures *a, @@ -1064,8 +1080,7 @@ int main(int argc, char *argv[]) msg = towire_struct_funding_locked(ctx, &fl); fl2 = fromwire_struct_funding_locked(ctx, msg); assert(funding_locked_eq(&fl, fl2)); - /* FIXME: Corruptions in the TLV can still parse correctly, but won't be equal. */ - /*test_corruption_tlv(&fl, fl2, funding_locked);*/ + test_corruption_tlv(&fl, fl2, funding_locked); memset(&as, 2, sizeof(as)); From 1657202dfd448951e7adb07c7ae75288788e864a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:26:31 +0930 Subject: [PATCH 02/20] wire/test: neaten and complete tlv checks. In particular, we didn't check the remote_addr in the init msg. Signed-off-by: Rusty Russell --- wire/test/run-peer-wire.c | 104 ++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 61 deletions(-) diff --git a/wire/test/run-peer-wire.c b/wire/test/run-peer-wire.c index 173032973486..1be1c016b93f 100644 --- a/wire/test/run-peer-wire.c +++ b/wire/test/run-peer-wire.c @@ -72,6 +72,14 @@ static void set_scid(struct short_channel_id *scid) (tal_count((p1)->field) == tal_count((p2)->field) \ && (tal_count((p1)->field) == 0 || memcmp((p1)->field, (p2)->field, tal_bytelen((p1)->field)) == 0)) +/* TLV field comparison: both unset, or both set and eqfn ok */ +#define eq_tlv(p1, p2, tlvname, eqfn) \ + (((p1)->tlvs == NULL && (p2)->tlvs == NULL) \ + || ((p1)->tlvs && (p2)->tlvs \ + && (((p1)->tlvs->tlvname == NULL && (p2)->tlvs->tlvname == NULL) \ + || ((p1)->tlvs->tlvname && (p2)->tlvs->tlvname && \ + eqfn((p1)->tlvs->tlvname, (p2)->tlvs->tlvname))))) + /* Convenience structs for everyone! */ struct msg_error { struct channel_id channel_id; @@ -814,22 +822,7 @@ static bool funding_locked_eq(const struct msg_funding_locked *a, if (!eq_upto(a, b, tlvs)) return false; - /* Both or neither */ - if (!a->tlvs != !b->tlvs) - return false; - - if (!a->tlvs) - return true; - - /* Both or neither */ - if (!a->tlvs->alias != !b->tlvs->alias) - return false; - - if (!a->tlvs->alias) - return true; - - return memeq(a->tlvs->alias, sizeof(a->tlvs->alias), - b->tlvs->alias, sizeof(b->tlvs->alias)); + return eq_tlv(a, b, alias, short_channel_id_eq); } static bool announcement_signatures_eq(const struct msg_announcement_signatures *a, @@ -878,34 +871,31 @@ static bool error_eq(const struct msg_error *a, && eq_var(a, b, data); } -static bool init_eq(const struct msg_init *a, - const struct msg_init *b) +static bool tlv_networks_eq(const struct bitcoin_blkid *a, + const struct bitcoin_blkid *b) { - if (!eq_var(a, b, globalfeatures) || !eq_var(a, b, localfeatures)) + if (tal_count(a) != tal_count(b)) return false; - /* Both or neither */ - if (!a->tlvs != !b->tlvs) - return false; + for (size_t i = 0; i < tal_count(a); i++) + if (!bitcoin_blkid_eq(&a[i], &b[i])) + return false; + return true; +} - if (!a->tlvs) - return true; +static bool talarr_eq(const void *a, const void *b) +{ + return memeq(a, tal_bytelen(a), b, tal_bytelen(b)); +} - /* Both or neither */ - if (!a->tlvs->networks != !b->tlvs->networks) +static bool init_eq(const struct msg_init *a, + const struct msg_init *b) +{ + if (!eq_var(a, b, globalfeatures) || !eq_var(a, b, localfeatures)) return false; - if (!a->tlvs->networks) - return true; - - if (tal_count(a->tlvs->networks) - != tal_count(b->tlvs->networks)) - return false; - for (size_t i = 0; i < tal_count(a->tlvs->networks); i++) - if (!bitcoin_blkid_eq(&a->tlvs->networks[i], - &b->tlvs->networks[i])) - return false; - return true; + return eq_tlv(a, b, networks, tlv_networks_eq) + && eq_tlv(a, b, remote_addr, talarr_eq); } static bool update_fee_eq(const struct msg_update_fee *a, @@ -982,28 +972,14 @@ lease_rates_eq(const struct lease_rates *a, static bool node_announcement_eq(const struct msg_node_announcement *a, const struct msg_node_announcement *b) { - /* Both or neither */ - if (!a->tlvs != !b->tlvs) - return false; - - if (!a->tlvs) - goto body_check; - - /* Both or neither */ - if (!a->tlvs->option_will_fund != !b->tlvs->option_will_fund) + if (!eq_with(a, b, node_id) + || !eq_field(a, b, rgb_color) + || !eq_field(a, b, alias) + || !eq_var(a, b, features) + || !eq_var(a, b, addresses)) return false; - if (a->tlvs->option_will_fund - && !lease_rates_eq(a->tlvs->option_will_fund, - b->tlvs->option_will_fund)) - return false; - -body_check: - return eq_with(a, b, node_id) - && eq_field(a, b, rgb_color) - && eq_field(a, b, alias) - && eq_var(a, b, features) - && eq_var(a, b, addresses); + return eq_tlv(a, b, option_will_fund, lease_rates_eq); } /* Try flipping each bit, try running short. */ @@ -1146,10 +1122,16 @@ int main(int argc, char *argv[]) init.tlvs = tlv_init_tlvs_new(ctx); init.tlvs->networks = tal_arr(init.tlvs, struct bitcoin_blkid, 1); init.tlvs->networks[0] = networks[i].genesis_blockhash; - msg = towire_struct_init(ctx, &init); - init2 = fromwire_struct_init(ctx, msg); - assert(init_eq(&init, init2)); - test_corruption_tlv(&init, init2, init); + for (size_t j = 0; j < 5; j++) { + if (j) { + init.tlvs->remote_addr = tal_arr(init.tlvs, u8, j); + memset(init.tlvs->remote_addr, j, j); + } + msg = towire_struct_init(ctx, &init); + init2 = fromwire_struct_init(ctx, msg); + assert(init_eq(&init, init2)); + test_corruption_tlv(&init, init2, init); + } } memset(&uf, 2, sizeof(uf)); From 0bb9cc3d840f54f5413d44b6d629c3f05148963a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:27:31 +0930 Subject: [PATCH 03/20] common: remove unused parameter "allow_deprecated" from parse_wireaddr_internal. Signed-off-by: Rusty Russell --- common/test/run-ip_port_parsing.c | 5 +---- common/test/run-wireaddr.c | 36 +++++++++++++++---------------- common/wireaddr.c | 2 +- common/wireaddr.h | 2 +- devtools/gossipwith.c | 2 +- lightningd/connect_control.c | 2 +- lightningd/options.c | 8 +++---- wallet/test/run-wallet.c | 6 +++--- wallet/wallet.c | 4 ++-- 9 files changed, 31 insertions(+), 36 deletions(-) diff --git a/common/test/run-ip_port_parsing.c b/common/test/run-ip_port_parsing.c index 6e386dff4bdd..f8150c511033 100644 --- a/common/test/run-ip_port_parsing.c +++ b/common/test/run-ip_port_parsing.c @@ -214,11 +214,8 @@ int main(int argc, char *argv[]) assert(!parse_wireaddr("odpzvneidqdf5hdq.onion:49150", &addr, 1, false, NULL)); assert(!parse_wireaddr("odpzvneidqdf5hdq.onion", &addr, 1, false, NULL)); - /* Neither allow_deprecated = true nor false will parse it now */ assert(!parse_wireaddr_internal("odpzvneidqdf5hdq.onion", &addr_int, 1, - false, false, false, false, NULL)); - assert(!parse_wireaddr_internal("odpzvneidqdf5hdq.onion", &addr_int, 1, - false, false, false, true, NULL)); + false, false, false, NULL)); assert(wireaddr_from_hostname(tmpctx, "odpzvneidqdf5hdq.onion", 1, NULL, NULL, NULL) == NULL); assert(wireaddr_from_hostname(tmpctx, "aaa.onion", 1, NULL, NULL, NULL) == NULL); diff --git a/common/test/run-wireaddr.c b/common/test/run-wireaddr.c index 2eec576ba192..8712563b009a 100644 --- a/common/test/run-wireaddr.c +++ b/common/test/run-wireaddr.c @@ -127,59 +127,59 @@ int main(int argc, char *argv[]) common_setup(argv[0]); /* Simple IPv4 address. */ - assert(parse_wireaddr_internal("127.0.0.1", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("127.0.0.1", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_WIREADDR; assert(parse_wireaddr("127.0.0.1:9735", &expect->u.wireaddr, 0, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* IPv4 address with port. */ - assert(parse_wireaddr_internal("127.0.0.1:1", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("127.0.0.1:1", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_WIREADDR; assert(parse_wireaddr("127.0.0.1:1", &expect->u.wireaddr, 0, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* Simple IPv6 address. */ - assert(parse_wireaddr_internal("::1", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("::1", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_WIREADDR; assert(parse_wireaddr("::1", &expect->u.wireaddr, DEFAULT_PORT, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* IPv6 address with port. */ - assert(parse_wireaddr_internal("[::1]:1", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("[::1]:1", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_WIREADDR; assert(parse_wireaddr("::1", &expect->u.wireaddr, 1, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* autotor address */ - assert(parse_wireaddr_internal("autotor:127.0.0.1", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("autotor:127.0.0.1", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_AUTOTOR; expect->u.torservice.port = DEFAULT_PORT; assert(parse_wireaddr("127.0.0.1", &expect->u.torservice.address, 9051, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* autotor address with port */ - assert(parse_wireaddr_internal("autotor:127.0.0.1:9055", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("autotor:127.0.0.1:9055", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_AUTOTOR; expect->u.torservice.port = DEFAULT_PORT; assert(parse_wireaddr("127.0.0.1", &expect->u.torservice.address, 9055, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* autotor address with torport */ - assert(parse_wireaddr_internal("autotor:127.0.0.1/torport=9055", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("autotor:127.0.0.1/torport=9055", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_AUTOTOR; expect->u.torservice.port = 9055; assert(parse_wireaddr("127.0.0.1", &expect->u.torservice.address, 9051, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* autotor address with port and torport */ - assert(parse_wireaddr_internal("autotor:127.0.0.1:9055/torport=10055", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("autotor:127.0.0.1:9055/torport=10055", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_AUTOTOR; expect->u.torservice.port = 10055; assert(parse_wireaddr("127.0.0.1", &expect->u.torservice.address, 9055, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* statictor address */ - assert(parse_wireaddr_internal("statictor:127.0.0.1", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("statictor:127.0.0.1", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_STATICTOR; expect->u.torservice.port = DEFAULT_PORT; memset(expect->u.torservice.blob, 0, sizeof(expect->u.torservice.blob)); @@ -188,28 +188,28 @@ int main(int argc, char *argv[]) assert(wireaddr_internal_eq(&addr, expect)); /* statictor address with port */ - assert(parse_wireaddr_internal("statictor:127.0.0.1:9055", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("statictor:127.0.0.1:9055", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_STATICTOR; expect->u.torservice.port = DEFAULT_PORT; assert(parse_wireaddr("127.0.0.1", &expect->u.torservice.address, 9055, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* statictor address with torport */ - assert(parse_wireaddr_internal("statictor:127.0.0.1/torport=9055", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("statictor:127.0.0.1/torport=9055", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_STATICTOR; expect->u.torservice.port = 9055; assert(parse_wireaddr("127.0.0.1", &expect->u.torservice.address, 9051, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* statictor address with port and torport */ - assert(parse_wireaddr_internal("statictor:127.0.0.1:9055/torport=10055", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("statictor:127.0.0.1:9055/torport=10055", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_STATICTOR; expect->u.torservice.port = 10055; assert(parse_wireaddr("127.0.0.1", &expect->u.torservice.address, 9055, NULL, &err)); assert(wireaddr_internal_eq(&addr, expect)); /* statictor address with port and torport and torblob */ - assert(parse_wireaddr_internal("statictor:127.0.0.1:9055/torport=10055/torblob=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("statictor:127.0.0.1:9055/torport=10055/torblob=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_STATICTOR; expect->u.torservice.port = 10055; /* This is actually nul terminated */ @@ -218,24 +218,24 @@ int main(int argc, char *argv[]) assert(wireaddr_internal_eq(&addr, expect)); /* local socket path */ - assert(parse_wireaddr_internal("/tmp/foo.sock", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(parse_wireaddr_internal("/tmp/foo.sock", &addr, DEFAULT_PORT, false, false, false, &err)); expect->itype = ADDR_INTERNAL_SOCKNAME; strcpy(expect->u.sockname, "/tmp/foo.sock"); assert(wireaddr_internal_eq(&addr, expect)); /* Unresolved */ - assert(!parse_wireaddr_internal("ozlabs.org", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(!parse_wireaddr_internal("ozlabs.org", &addr, DEFAULT_PORT, false, false, false, &err)); assert(streq(err, "Needed DNS, but lookups suppressed")); - assert(parse_wireaddr_internal("ozlabs.org", &addr, DEFAULT_PORT, false, false, true, false, &err)); + assert(parse_wireaddr_internal("ozlabs.org", &addr, DEFAULT_PORT, false, false, true, &err)); expect->itype = ADDR_INTERNAL_FORPROXY; strcpy(expect->u.unresolved.name, "ozlabs.org"); expect->u.unresolved.port = DEFAULT_PORT; assert(wireaddr_internal_eq(&addr, expect)); /* Unresolved with port */ - assert(!parse_wireaddr_internal("ozlabs.org:1234", &addr, DEFAULT_PORT, false, false, false, false, &err)); + assert(!parse_wireaddr_internal("ozlabs.org:1234", &addr, DEFAULT_PORT, false, false, false, &err)); assert(streq(err, "Needed DNS, but lookups suppressed")); - assert(parse_wireaddr_internal("ozlabs.org:1234", &addr, DEFAULT_PORT, false, false, true, false, &err)); + assert(parse_wireaddr_internal("ozlabs.org:1234", &addr, DEFAULT_PORT, false, false, true, &err)); expect->itype = ADDR_INTERNAL_FORPROXY; strcpy(expect->u.unresolved.name, "ozlabs.org"); expect->u.unresolved.port = 1234; diff --git a/common/wireaddr.c b/common/wireaddr.c index 4246a460cdff..4950d1510aed 100644 --- a/common/wireaddr.c +++ b/common/wireaddr.c @@ -586,7 +586,7 @@ bool wireaddr_internal_eq(const struct wireaddr_internal *a, bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr, u16 port, bool wildcard_ok, bool dns_ok, - bool unresolved_ok, bool allow_deprecated, + bool unresolved_ok, const char **err_msg) { u16 splitport; diff --git a/common/wireaddr.h b/common/wireaddr.h index 751cd8c8abfa..bdae7788fb30 100644 --- a/common/wireaddr.h +++ b/common/wireaddr.h @@ -158,7 +158,7 @@ bool is_dnsaddr(const char *arg); bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr, u16 port, bool wildcard_ok, bool dns_ok, - bool unresolved_ok, bool allow_deprecated, + bool unresolved_ok, const char **err_msg); void towire_wireaddr_internal(u8 **pptr, diff --git a/devtools/gossipwith.c b/devtools/gossipwith.c index ada35b14cacc..365fb4f04646 100644 --- a/devtools/gossipwith.c +++ b/devtools/gossipwith.c @@ -326,7 +326,7 @@ int main(int argc, char *argv[]) (int)(at - argv[1]), argv[1]); if (!parse_wireaddr_internal(at+1, &addr, chainparams_get_ln_port(chainparams), NULL, - true, false, true, &err_msg)) + true, false, &err_msg)) opt_usage_exit_fail("%s '%s'", err_msg, argv[1]); switch (addr.itype) { diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c index a52117e90429..dcc8da297e91 100644 --- a/lightningd/connect_control.c +++ b/lightningd/connect_control.c @@ -201,7 +201,7 @@ static struct command_result *json_connect(struct command *cmd, if (!parse_wireaddr_internal(id_addr.host, addr, port, false, !cmd->ld->always_use_proxy && !cmd->ld->pure_tor_setup, - true, deprecated_apis, + true, &err_msg)) { return command_fail(cmd, LIGHTNINGD, "Host %s:%u not valid: %s", diff --git a/lightningd/options.c b/lightningd/options.c index 54f5213b118a..0bec067046e6 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -237,7 +237,7 @@ static char *opt_add_addr_withtype(const char *arg, || ala != ADDR_ANNOUNCE) { if (!parse_wireaddr_internal(arg, &wi, ld->portnum, wildcard_ok, dns_ok, false, - deprecated_apis, &err_msg)) { + &err_msg)) { return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg); } @@ -318,8 +318,7 @@ static char *opt_add_addr(const char *arg, struct lightningd *ld) struct wireaddr_internal addr; /* handle in case you used the addr option with an .onion */ - if (parse_wireaddr_internal(arg, &addr, 0, true, false, true, - deprecated_apis, NULL)) { + if (parse_wireaddr_internal(arg, &addr, 0, true, false, true, NULL)) { if (addr.itype == ADDR_INTERNAL_WIREADDR && addr.u.wireaddr.type == ADDR_TYPE_TOR_V3) { log_unusual(ld->log, "You used `--addr=%s` option with an .onion address, please use" @@ -365,8 +364,7 @@ static char *opt_add_bind_addr(const char *arg, struct lightningd *ld) struct wireaddr_internal addr; /* handle in case you used the bind option with an .onion */ - if (parse_wireaddr_internal(arg, &addr, 0, true, false, true, - deprecated_apis, NULL)) { + if (parse_wireaddr_internal(arg, &addr, 0, true, false, true, NULL)) { if (addr.itype == ADDR_INTERNAL_WIREADDR && addr.u.wireaddr.type == ADDR_TYPE_TOR_V3) { log_unusual(ld->log, "You used `--bind-addr=%s` option with an .onion address," diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index 29593e16fe00..a3aa98eb6f24 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -1098,7 +1098,7 @@ static bool test_wallet_outputs(struct lightningd *ld, const tal_t *ctx) /* Add another utxo that's CSV-locked for 5 blocks */ parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false, - true, NULL); + NULL); channel.peer = new_peer(ld, 0, &id, &addr, false); channel.dbid = 1; channel.type = channel_type_anchor_outputs(tmpctx); @@ -1395,7 +1395,7 @@ static bool test_channel_crud(struct lightningd *ld, const tal_t *ctx) mempat(scriptpubkey, tal_count(scriptpubkey)); c1.first_blocknum = 1; parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false, - true, NULL); + NULL); c1.final_key_idx = 1337; p = new_peer(ld, 0, &id, &addr, false); c1.peer = p; @@ -1558,7 +1558,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) pubkey_from_der(tal_hexdata(w, "02a1633cafcc01ebfb6d78e39f687a1f0995c62fc95f51ead10a02ee0be551b5dc", 66), 33, &pk); node_id_from_pubkey(&id, &pk); parse_wireaddr_internal("localhost:1234", &addr, 0, false, false, false, - true, NULL); + NULL); /* new channel! */ p = new_peer(ld, 0, &id, &addr, false); diff --git a/wallet/wallet.c b/wallet/wallet.c index c287a3934017..f4f740a75509 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -839,11 +839,11 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid) /* This can happen for peers last seen on Torv2! */ addrstr = db_col_strdup(tmpctx, stmt, "address"); if (!parse_wireaddr_internal(addrstr, &addr, chainparams_get_ln_port(chainparams), - false, false, true, true, NULL)) { + false, false, true, NULL)) { log_unusual(w->log, "Unparsable peer address %s: replacing", addrstr); parse_wireaddr_internal("127.0.0.1:1", &addr, chainparams_get_ln_port(chainparams), - false, false, true, true, NULL); + false, false, true, NULL); } /* FIXME: save incoming in db! */ From e241348d438e334215a7667e65014b5c160763c1 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:28:31 +0930 Subject: [PATCH 04/20] lightningd: remove double-wrapped rpc_command hook. Somehow we missed this deprecation, found by grep. Changelog-Removed: JSON API: Removed double wrapping of `rpc_command` payload in `rpc_command` JSON field (deprecated v0.8.2) Signed-off-by: Rusty Russell --- lightningd/jsonrpc.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index 357297f2f3a4..d48ec8509289 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -664,11 +664,6 @@ static void rpc_command_hook_serialize(struct rpc_command_hook_payload *p, char *key; json_object_start(s, "rpc_command"); -#ifdef COMPAT_V081 - if (deprecated_apis) - json_add_tok(s, "rpc_command", p->request, p->buffer); -#endif - json_for_each_obj(i, tok, p->request) { key = tal_strndup(NULL, p->buffer + tok->start, tok->end - tok->start); From 986a0c2880f84d7f450e9f88f9a4b47e1946d3f7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:29:31 +0930 Subject: [PATCH 05/20] lightningd: always require "jsonrpc": "2.0" in request. Changelog-Removed: JSONRPC: RPC framework now requires the `"jsonrpc"` property inside the request (deprecated in v0.10.2) Signed-off-by: Rusty Russell --- lightningd/jsonrpc.c | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index d48ec8509289..3b758ddcf22a 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -677,7 +677,7 @@ static void replace_command(struct rpc_command_hook_payload *p, const char *buffer, const jsmntok_t *replacetok) { - const jsmntok_t *method = NULL, *params = NULL; + const jsmntok_t *method = NULL, *params = NULL, *jsonrpc; const char *bad; /* Must contain "method", "params" and "id" */ @@ -709,14 +709,10 @@ static void replace_command(struct rpc_command_hook_payload *p, goto fail; } - // deprecated phase to give the possibility to all to migrate and stay safe - // from this more restrictive change. - if (!deprecated_apis) { - const jsmntok_t *jsonrpc = json_get_member(buffer, replacetok, "jsonrpc"); - if (!jsonrpc || jsonrpc->type != JSMN_STRING || !json_tok_streq(buffer, jsonrpc, "2.0")) { - bad = "jsonrpc: \"2.0\" must be specified in the request"; - goto fail; - } + jsonrpc = json_get_member(buffer, replacetok, "jsonrpc"); + if (!jsonrpc || jsonrpc->type != JSMN_STRING || !json_tok_streq(buffer, jsonrpc, "2.0")) { + bad = "jsonrpc: \"2.0\" must be specified in the request"; + goto fail; } was_pending(command_exec(p->cmd->jcon, p->cmd, buffer, replacetok, @@ -853,7 +849,7 @@ REGISTER_PLUGIN_HOOK(rpc_command, static struct command_result * parse_request(struct json_connection *jcon, const jsmntok_t tok[]) { - const jsmntok_t *method, *id, *params; + const jsmntok_t *method, *id, *params, *jsonrpc; struct command *c; struct rpc_command_hook_payload *rpc_hook; bool completed; @@ -881,13 +877,11 @@ parse_request(struct json_connection *jcon, const jsmntok_t tok[]) // Adding a deprecated phase to make sure that all the Core Lightning wrapper // can migrate all the frameworks - if (!deprecated_apis) { - const jsmntok_t *jsonrpc = json_get_member(jcon->buffer, tok, "jsonrpc"); + jsonrpc = json_get_member(jcon->buffer, tok, "jsonrpc"); - if (!jsonrpc || jsonrpc->type != JSMN_STRING || !json_tok_streq(jcon->buffer, jsonrpc, "2.0")) { - json_command_malformed(jcon, "null", "jsonrpc: \"2.0\" must be specified in the request"); - return NULL; - } + if (!jsonrpc || jsonrpc->type != JSMN_STRING || !json_tok_streq(jcon->buffer, jsonrpc, "2.0")) { + json_command_malformed(jcon, "null", "jsonrpc: \"2.0\" must be specified in the request"); + return NULL; } /* Allocate the command off of the `jsonrpc` object and not From 560b7efd7b6b80cf172d0eb860cadb9a7cb4cd25 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:30:31 +0930 Subject: [PATCH 06/20] lightningd: don't allow old listforwards arg order. Changelog-Removed: Old order of the `status` parameter in the `listforwards` rpc command (deprecated in v0.10.2) Signed-off-by: Rusty Russell --- lightningd/peer_htlcs.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index a9d74e6c9879..dac8545496cd 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -2853,30 +2853,13 @@ static struct command_result *json_listforwards(struct command *cmd, const char *status_str; enum forward_status status = FORWARD_ANY; - // TODO: We will remove soon after the deprecated period. - if (params && deprecated_apis && params->type == JSMN_ARRAY) { - struct short_channel_id scid; - /* We need to catch [ null, null, "settled" ], and - * [ "1x2x3" ] as old-style */ - if ((params->size > 0 && json_to_short_channel_id(buffer, params + 1, &scid)) || - (params->size == 3 && !json_to_short_channel_id(buffer, params + 3, &scid))) { - if (!param(cmd, buffer, params, - p_opt("in_channel", param_short_channel_id, &chan_in), - p_opt("out_channel", param_short_channel_id, &chan_out), - p_opt("status", param_string, &status_str), - NULL)) - return command_param_failed(); - goto parsed; - } - } - if (!param(cmd, buffer, params, p_opt("status", param_string, &status_str), p_opt("in_channel", param_short_channel_id, &chan_in), p_opt("out_channel", param_short_channel_id, &chan_out), NULL)) return command_param_failed(); - parsed: + if (status_str && !string_to_forward_status(status_str, &status)) return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Unrecognized status: %s", status_str); From 13738d16970beb606505756d0b66775680d661f4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:31:31 +0930 Subject: [PATCH 07/20] lightningd: do inline parsing for listforwards status parameter We can do this now the function is cleaned up. Always better to do the work inside param() since then `check` gets the benefit. Signed-off-by: Rusty Russell --- lightningd/peer_htlcs.c | 34 ++++++++++++++++++++++------------ wallet/wallet.c | 12 +++++++----- wallet/wallet.h | 3 ++- 3 files changed, 31 insertions(+), 18 deletions(-) diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index dac8545496cd..62a6993ad71f 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -2839,6 +2839,22 @@ static void listforwardings_add_forwardings(struct json_stream *response, tal_free(forwardings); } +static struct command_result *param_forward_status(struct command *cmd, + const char *name, + const char *buffer, + const jsmntok_t *tok, + enum forward_status **status) +{ + *status = tal(cmd, enum forward_status); + if (string_to_forward_status(buffer + tok->start, + tok->end - tok->start, + *status)) + return NULL; + + return command_fail_badparam(cmd, name, buffer, tok, + "Unrecognized status"); +} + static struct command_result *json_listforwards(struct command *cmd, const char *buffer, const jsmntok_t *obj UNNEEDED, @@ -2846,25 +2862,19 @@ static struct command_result *json_listforwards(struct command *cmd, { struct json_stream *response; - - struct short_channel_id *chan_in; - struct short_channel_id *chan_out; - - const char *status_str; - enum forward_status status = FORWARD_ANY; + struct short_channel_id *chan_in, *chan_out; + enum forward_status *status; if (!param(cmd, buffer, params, - p_opt("status", param_string, &status_str), + p_opt_def("status", param_forward_status, &status, + FORWARD_ANY), p_opt("in_channel", param_short_channel_id, &chan_in), p_opt("out_channel", param_short_channel_id, &chan_out), NULL)) return command_param_failed(); - if (status_str && !string_to_forward_status(status_str, &status)) - return command_fail(cmd, JSONRPC2_INVALID_PARAMS, "Unrecognized status: %s", status_str); - response = json_stream_success(cmd); - listforwardings_add_forwardings(response, cmd->ld->wallet, status, chan_in, chan_out); + listforwardings_add_forwardings(response, cmd->ld->wallet, *status, chan_in, chan_out); return command_success(cmd, response); } @@ -2873,6 +2883,6 @@ static const struct json_command listforwards_command = { "listforwards", "channels", json_listforwards, - "List all forwarded payments and their information optionally filtering by [in_channel] [out_channel] and [state]" + "List all forwarded payments and their information optionally filtering by [status], [in_channel] and [out_channel]" }; AUTODATA(json_command, &listforwards_command); diff --git a/wallet/wallet.c b/wallet/wallet.c index f4f740a75509..9cc9e8e58caa 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -4485,18 +4485,20 @@ struct amount_msat wallet_total_forward_fees(struct wallet *w) return total; } -bool string_to_forward_status(const char *status_str, enum forward_status *status) +bool string_to_forward_status(const char *status_str, + size_t len, + enum forward_status *status) { - if (streq(status_str, "offered")) { + if (memeqstr(status_str, len, "offered")) { *status = FORWARD_OFFERED; return true; - } else if (streq(status_str, "settled")) { + } else if (memeqstr(status_str, len, "settled")) { *status = FORWARD_SETTLED; return true; - } else if (streq(status_str, "failed")) { + } else if (memeqstr(status_str, len, "failed")) { *status = FORWARD_FAILED; return true; - } else if (streq(status_str, "local_failed")) { + } else if (memeqstr(status_str, len, "local_failed")) { *status = FORWARD_LOCAL_FAILED; return true; } diff --git a/wallet/wallet.h b/wallet/wallet.h index 425c8637db68..f6cf987bb94d 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -158,7 +158,8 @@ static inline const char* forward_status_name(enum forward_status status) abort(); } -bool string_to_forward_status(const char *status_str, enum forward_status *status); +bool string_to_forward_status(const char *status_str, size_t len, + enum forward_status *status); /* /!\ This is a DB ENUM, please do not change the numbering of any * already defined elements (adding is ok) /!\ */ From c6b28324f32728e268f5a2affce45f44d501686c Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:32:31 +0930 Subject: [PATCH 08/20] plugins: require usage for plugin APIs. Changelog-Removed: JSON-RPC: plugins must supply `usage` parameter (deprecated v0.7) Signed-off-by: Rusty Russell --- lightningd/plugin.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lightningd/plugin.c b/lightningd/plugin.c index ea9fb5c75872..5ac7abcb8810 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -1205,11 +1205,9 @@ static const char *plugin_rpcmethod_add(struct plugin *plugin, cmd->verbose = cmd->description; if (usagetok) usage = json_strdup(tmpctx, buffer, usagetok); - else if (!deprecated_apis) { + else return tal_fmt(plugin, "\"usage\" not provided by plugin"); - } else - usage = "[params]"; if (deptok) { if (!json_to_bool(buffer, deptok, &cmd->deprecated)) From ffd6b70e225b89dd0bbaf00f956254b423dad932 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:33:31 +0930 Subject: [PATCH 09/20] lightningd: remove `use_proxy_always` parameter to plugin init. Changelog-Removed: Plugins: plugin init `use_proxy_always` (deprecated v0.10.2) Signed-off-by: Rusty Russell --- lightningd/plugin.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 5ac7abcb8810..c0bd267242e4 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -1884,9 +1884,6 @@ plugin_populate_init_request(struct plugin *plugin, struct jsonrpc_request *req) json_add_address(req->stream, "proxy", ld->proxyaddr); json_add_bool(req->stream, "torv3-enabled", true); json_add_bool(req->stream, "always_use_proxy", ld->always_use_proxy); - if (deprecated_apis) - json_add_bool(req->stream, "use_proxy_always", - ld->always_use_proxy); } json_object_start(req->stream, "feature_set"); for (enum feature_place fp = 0; fp < NUM_FEATURE_PLACE; fp++) { From 185be8ddfcdf5da9077ccdb58722b764edec924d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:34:31 +0930 Subject: [PATCH 10/20] listchannels: don't show "htlc_maximum_msat" if channel_update didn't set it. It was deprecated in v0.10.1, but only one channel on the network doesn't set it now anyway, and we'll be ignoring that soon. Signed-off-by: Rusty Russell --- plugins/topology.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/plugins/topology.c b/plugins/topology.c index dc4f2fc55854..56f8154704a5 100644 --- a/plugins/topology.c +++ b/plugins/topology.c @@ -281,17 +281,6 @@ static void json_add_halfchan(struct json_stream *response, json_add_amount_msat_only(response, "htlc_minimum_msat", htlc_minimum_msat); - /* We used to always print this, but that's weird */ - if (deprecated_apis && !(message_flags & 1)) { - if (!amount_sat_to_msat(&htlc_maximum_msat, capacity)) - plugin_err(plugin, - "Channel with impossible capacity %s", - type_to_string(tmpctx, - struct amount_sat, - &capacity)); - message_flags = 1; - } - if (message_flags & 1) json_add_amount_msat_only(response, "htlc_maximum_msat", htlc_maximum_msat); From b90ba770dca2a97e868771aa26ccaeb452fe117d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:35:31 +0930 Subject: [PATCH 11/20] offers: update to remove "vendor" and "timestamp" fields. Changelog-EXPERIMENTAL: remove "vendor" (use "issuer") and "timestamp" (use "created_at") fields (deprecated v0.10.2). --- plugins/offers.c | 17 ++------------ plugins/offers_offer.c | 50 ------------------------------------------ 2 files changed, 2 insertions(+), 65 deletions(-) diff --git a/plugins/offers.c b/plugins/offers.c index a1495bd2f9c6..5fd2cf11df7a 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -412,14 +412,9 @@ static void json_add_offer(struct json_stream *js, const struct tlv_offer *offer valid = false; } - if (offer->issuer) { + if (offer->issuer) json_add_stringn(js, "issuer", offer->issuer, tal_bytelen(offer->issuer)); - if (deprecated_apis) { - json_add_stringn(js, "vendor", offer->issuer, - tal_bytelen(offer->issuer)); - } - } if (offer->features) json_add_hex_talarr(js, "features", offer->features); if (offer->absolute_expiry) @@ -579,14 +574,9 @@ static void json_add_b12_invoice(struct json_stream *js, valid = false; } - if (invoice->issuer) { + if (invoice->issuer) json_add_stringn(js, "issuer", invoice->issuer, tal_bytelen(invoice->issuer)); - if (deprecated_apis) { - json_add_stringn(js, "vendor", invoice->issuer, - tal_bytelen(invoice->issuer)); - } - } if (invoice->features) json_add_hex_talarr(js, "features", invoice->features); if (invoice->paths) { @@ -644,9 +634,6 @@ static void json_add_b12_invoice(struct json_stream *js, * - MUST reject the invoice if `created_at` is not present. */ if (invoice->created_at) { - /* FIXME: Remove soon! */ - if (deprecated_apis) - json_add_u64(js, "timestamp", *invoice->created_at); json_add_u64(js, "created_at", *invoice->created_at); } else { json_add_string(js, "warning_invoice_missing_created_at", diff --git a/plugins/offers_offer.c b/plugins/offers_offer.c index ee096883071b..520513daddfe 100644 --- a/plugins/offers_offer.c +++ b/plugins/offers_offer.c @@ -322,36 +322,6 @@ struct command_result *json_offer(struct command *cmd, offinfo->offer = offer = tlv_offer_new(offinfo); - /* "issuer" used to be called "vendor" */ - if (deprecated_apis - && params - && params->type == JSMN_OBJECT - && json_get_member(buffer, params, "vendor")) { - if (!param(cmd, buffer, params, - p_req("amount", param_amount, offer), - p_req("description", param_escaped_string, &desc), - p_opt("vendor", param_escaped_string, &issuer), - p_opt("label", param_escaped_string, &offinfo->label), - p_opt("quantity_min", param_u64, &offer->quantity_min), - p_opt("quantity_max", param_u64, &offer->quantity_max), - p_opt("absolute_expiry", param_u64, &offer->absolute_expiry), - p_opt("recurrence", param_recurrence, &offer->recurrence), - p_opt("recurrence_base", - param_recurrence_base, - &offer->recurrence_base), - p_opt("recurrence_paywindow", - param_recurrence_paywindow, - &offer->recurrence_paywindow), - p_opt("recurrence_limit", - param_number, - &offer->recurrence_limit), - p_opt_def("single_use", param_bool, - &offinfo->single_use, false), - NULL)) - return command_param_failed(); - goto after_params; - } - if (!param(cmd, buffer, params, p_req("amount", param_amount, offer), p_req("description", param_escaped_string, &desc), @@ -376,7 +346,6 @@ struct command_result *json_offer(struct command *cmd, NULL)) return command_param_failed(); -after_params: if (!offers_enabled) return command_fail(cmd, LIGHTNINGD, "experimental-offers not enabled"); @@ -466,24 +435,6 @@ struct command_result *json_offerout(struct command *cmd, offer = tlv_offer_new(cmd); - /* "issuer" used to be called "vendor" */ - if (deprecated_apis - && params - && params->type == JSMN_OBJECT - && json_get_member(buffer, params, "vendor")) { - if (!param(cmd, buffer, params, - p_req("amount", param_msat_or_any, offer), - p_req("description", param_escaped_string, &desc), - p_opt("vendor", param_escaped_string, &issuer), - p_opt("label", param_escaped_string, &label), - p_opt("absolute_expiry", param_u64, &offer->absolute_expiry), - p_opt("refund_for", param_invoice_payment_hash, &offer->refund_for), - /* FIXME: hints support! */ - NULL)) - return command_param_failed(); - goto after_params; - } - if (!param(cmd, buffer, params, p_req("amount", param_msat_or_any, offer), p_req("description", param_escaped_string, &desc), @@ -495,7 +446,6 @@ struct command_result *json_offerout(struct command *cmd, NULL)) return command_param_failed(); -after_params: if (!offers_enabled) return command_fail(cmd, LIGHTNINGD, "experimental-offers not enabled"); From 258cdf84ed05a585a96c4c78d3b8a21313b8db41 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:36:31 +0930 Subject: [PATCH 12/20] offers: remove backwards-compatiblity invoice_request signatures. We changed the field name in v0.11.0, so this breaks compat with v0.10.2. Signed-off-by: Rusty Russell --- lightningd/offer.c | 11 +++-------- plugins/fetchinvoice.c | 5 +---- plugins/offers.c | 21 +++------------------ plugins/offers_invreq_hook.c | 18 +++--------------- tests/test_pay.py | 14 -------------- 5 files changed, 10 insertions(+), 59 deletions(-) diff --git a/lightningd/offer.c b/lightningd/offer.c index f80a7b39c442..67ca0e10fbad 100644 --- a/lightningd/offer.c +++ b/lightningd/offer.c @@ -473,14 +473,9 @@ static struct command_result *json_createinvoicerequest(struct command *cmd, invreq->fields = tlv_make_fields(invreq, tlv_invoice_request); merkle_tlv(invreq->fields, &merkle); invreq->signature = tal(invreq, struct bip340sig); - if (deprecated_apis) - hsm_sign_b12(cmd->ld, "invoice_request", "payer_signature", - &merkle, invreq->payer_info, invreq->payer_key, - invreq->signature); - else - hsm_sign_b12(cmd->ld, "invoice_request", "signature", - &merkle, invreq->payer_info, invreq->payer_key, - invreq->signature); + hsm_sign_b12(cmd->ld, "invoice_request", "signature", + &merkle, invreq->payer_info, invreq->payer_key, + invreq->signature); response = json_stream_success(cmd); json_add_string(response, "bolt12", invrequest_encode(tmpctx, invreq)); diff --git a/plugins/fetchinvoice.c b/plugins/fetchinvoice.c index b7f3abe70cec..cbf00bfc3188 100644 --- a/plugins/fetchinvoice.c +++ b/plugins/fetchinvoice.c @@ -1196,10 +1196,7 @@ force_payer_secret(struct command *cmd, "Could not remarshall invreq %s", tal_hex(tmpctx, msg)); merkle_tlv(sent->invreq->fields, &merkle); - if (deprecated_apis) - sighash_from_merkle("invoice_request", "payer_signature", &merkle, &sha); - else - sighash_from_merkle("invoice_request", "signature", &merkle, &sha); + sighash_from_merkle("invoice_request", "signature", &merkle, &sha); sent->invreq->signature = tal(invreq, struct bip340sig); if (!secp256k1_schnorrsig_sign32(secp256k1_ctx, diff --git a/plugins/offers.c b/plugins/offers.c index 5fd2cf11df7a..4a64e3729abd 100644 --- a/plugins/offers.c +++ b/plugins/offers.c @@ -776,24 +776,9 @@ static void json_add_invoice_request(struct json_stream *js, "signature", invreq->payer_key, invreq->signature)) { - bool sig_valid; - - if (deprecated_apis) { - /* The old name? */ - sig_valid = bolt12_check_signature(invreq->fields, - "invoice_request", - "payer_signature", - invreq->payer_key, - invreq->signature); - } else { - sig_valid = false; - } - - if (!sig_valid) { - json_add_string(js, "warning_invoice_request_invalid_signature", - "Bad signature"); - valid = false; - } + json_add_string(js, "warning_invoice_request_invalid_signature", + "Bad signature"); + valid = false; } } else { json_add_string(js, "warning_invoice_request_missing_signature", diff --git a/plugins/offers_invreq_hook.c b/plugins/offers_invreq_hook.c index a75817bbae98..ff6a0fc3a5e5 100644 --- a/plugins/offers_invreq_hook.c +++ b/plugins/offers_invreq_hook.c @@ -431,23 +431,11 @@ static bool check_payer_sig(struct command *cmd, merkle_tlv(invreq->fields, &merkle); sighash_from_merkle("invoice_request", "signature", &merkle, &sighash); - if (secp256k1_schnorrsig_verify(secp256k1_ctx, - sig->u8, - sighash.u.u8, sizeof(sighash.u.u8), &payer_key->pubkey) == 1) - return true; - - if (!deprecated_apis) - return false; - - /* Try old name */ - plugin_log(cmd->plugin, LOG_DBG, - "Testing invoice_request with old name 'payer_signature'"); - sighash_from_merkle("invoice_request", "payer_signature", - &merkle, &sighash); - return secp256k1_schnorrsig_verify(secp256k1_ctx, sig->u8, - sighash.u.u8, sizeof(sighash.u.u8), &payer_key->pubkey) == 1; + sighash.u.u8, + sizeof(sighash.u.u8), + &payer_key->pubkey) == 1; } static struct command_result *invreq_amount_by_quantity(struct command *cmd, diff --git a/tests/test_pay.py b/tests/test_pay.py index 8360b81f59f0..e10cf0afb07b 100644 --- a/tests/test_pay.py +++ b/tests/test_pay.py @@ -4540,20 +4540,6 @@ def test_offer(node_factory, bitcoind): assert 'recurrence: every 600 seconds paywindow -10 to +600 (pay proportional)\n' in output -def test_deprecated_offer(node_factory, bitcoind): - """Test that we allow old invreq name `payer_signature` with deprecated_apis""" - l1, l2 = node_factory.line_graph(2, opts={'experimental-offers': None, - 'allow-deprecated-apis': True}) - - offer = l2.rpc.call('offer', {'amount': 10000, - 'description': 'test'})['bolt12'] - - inv = l1.rpc.call('fetchinvoice', {'offer': offer})['invoice'] - l2.daemon.wait_for_log("Testing invoice_request with old name 'payer_signature'") - - l1.rpc.pay(inv) - - @pytest.mark.developer("dev-no-modern-onion is DEVELOPER-only") def test_fetchinvoice_3hop(node_factory, bitcoind): l1, l2, l3, l4 = node_factory.line_graph(4, wait_for_announce=True, From d3a573dc3186cbbe60b0916204cc02e8414f4514 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:37:31 +0930 Subject: [PATCH 13/20] hsmtool: remove hsm_secret passwords on cmdline support in `dumponchaindescriptors`. Changelog-Removed: `hsmtool`: hsm_secret (ignored) on cmdline for dumponchaindescriptors (deprecated in v0.9.3) Signed-off-by: Rusty Russell --- tools/hsmtool.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tools/hsmtool.c b/tools/hsmtool.c index 226046365c96..4b392affc2c6 100644 --- a/tools/hsmtool.c +++ b/tools/hsmtool.c @@ -719,11 +719,6 @@ int main(int argc, char *argv[]) if (argc > 3) net = argv[3]; - /* Previously, we accepted hsm_secret passwords on the command line. - * This shifted the location of the network parameter. - * TODO: remove this 3 releases after v0.9.3 */ - if (deprecated_apis && argc > 4) - net = argv[4]; if (net && streq(net, "testnet")) is_testnet = true; From a0eeb0b6ef42d7f1c8f5d611a44b0fa2f932495a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:38:31 +0930 Subject: [PATCH 14/20] devtools/bolt-catchup.sh: a tool to update the specs, one commit at a time. This would be more effective if we didn't *merge* in the specs repo, but still. Usage: ./devtools/bolt-catchup.sh It goes through one commit at a time, up to current HEAD, and stops when there are changes, or quotes change. Signed-off-by: Rusty Russell --- devtools/bolt-catchup.sh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100755 devtools/bolt-catchup.sh diff --git a/devtools/bolt-catchup.sh b/devtools/bolt-catchup.sh new file mode 100755 index 000000000000..60f5662e57d8 --- /dev/null +++ b/devtools/bolt-catchup.sh @@ -0,0 +1,25 @@ +#! /bin/sh +# A script to upgrade spec versions one at a time, stop when something changes. + +set -e +BOLTDIR=${1:-../bolts} + +HEAD=$(git -C "$BOLTDIR" show --format=%H -s) +VERSION=$(sed -n 's/^DEFAULT_BOLTVERSION[ ]*:=[ ]*\([0-9a-f]*\)/\1/p' < Makefile) + +# We only change Makefile at exit, otherwise git diff shows the difference, of course! +finalize_and_exit() +{ + sed "s/^DEFAULT_BOLTVERSION[ ]*:=[ ]*\([0-9a-f]*\)/DEFAULT_BOLTVERSION := $v/" < Makefile > Makefile.$$ && mv Makefile.$$ Makefile + exit 0 +} + +for v in $(git -C "$BOLTDIR" show "$VERSION..$HEAD" --format=%H -s | tac); do + echo "Trying $v..." + make -s extract-bolt-csv DEFAULT_BOLTVERSION="$v" || finalize_and_exit + git diff --exit-code || finalize_and_exit + make -s check-source-bolt DEFAULT_BOLTVERSION="$v" || finalize_and_exit +done + +echo "No changes, simply upgrading to $v..." +finalize_and_exit From 00bce5e81b432dc6e19c78c23b6e1c154e78ea02 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:39:31 +0930 Subject: [PATCH 15/20] doc: increase BOLT level to 03468e17563650fb9bfe58b2da4d1e5d28e92009 `flags` in `channel_disabled` gets renamed. We don't use it anyway. Signed-off-by: Rusty Russell --- Makefile | 2 +- wire/onion_wire.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 5d21d7f51e5b..39b600335f0f 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ CCANDIR := ccan # Where we keep the BOLT RFCs BOLTDIR := ../bolts/ -DEFAULT_BOLTVERSION := 105c2e5e9f17c68e8c19dc4ca548600a0b8f66f0 +DEFAULT_BOLTVERSION := 03468e17563650fb9bfe58b2da4d1e5d28e92009 # Can be overridden on cmdline. BOLTVERSION := $(DEFAULT_BOLTVERSION) diff --git a/wire/onion_wire.csv b/wire/onion_wire.csv index 9f255bdaf017..09f7920fdbce 100644 --- a/wire/onion_wire.csv +++ b/wire/onion_wire.csv @@ -99,7 +99,7 @@ msgdata,final_incorrect_cltv_expiry,cltv_expiry,u32, msgtype,final_incorrect_htlc_amount,19 msgdata,final_incorrect_htlc_amount,incoming_htlc_amt,u64, msgtype,channel_disabled,UPDATE|20 -msgdata,channel_disabled,flags,u16, +msgdata,channel_disabled,disabled_flags,u16, msgdata,channel_disabled,len,u16, msgdata,channel_disabled,channel_update,byte,len msgtype,expiry_too_far,21 From 4543a7d4d3067bd36081b0fe881929a981a48438 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:40:31 +0930 Subject: [PATCH 16/20] doc: update BOLTs to bc86304b4b0af5fd5ce9d24f74e2ebbceb7e2730 This contains the zeroconf stuff, with funding_locked renamed to channel_ready. I change that everywhere, and try to fix up the comments. Also the `alias` field is called `short_channel_id`. Signed-off-by: Rusty Russell Changelog-Changed: Protocol: `funding_locked` is now called `channel_ready` as per latest BOLTs. --- Makefile | 2 +- channeld/channeld.c | 90 +++++++++++----------- channeld/channeld_wire.csv | 12 +-- closingd/closingd.c | 4 +- common/channel_type.c | 9 ++- common/gossip_constants.h | 2 +- common/gossip_store.c | 2 +- connectd/gossip_rcvd_filter.c | 2 +- connectd/multiplex.c | 2 +- gossipd/gossipd.c | 2 +- lightningd/channel.c | 6 +- lightningd/channel.h | 4 +- lightningd/channel_control.c | 43 +++++------ lightningd/channel_control.h | 6 +- lightningd/dual_open_control.c | 20 +++-- lightningd/onchain_control.c | 2 +- lightningd/opening_common.c | 9 ++- lightningd/opening_control.c | 14 ++-- openingd/dualopend.c | 70 ++++++++--------- openingd/openingd.c | 5 +- tests/test_closing.py | 2 +- tests/test_connection.py | 8 +- tests/test_opening.py | 14 ++-- wallet/wallet.c | 2 +- wire/extracted_peer_03_openchannelv2.patch | 6 +- wire/extracted_peer_06_zeroconf.patch | 14 ---- wire/peer_wire.c | 8 +- wire/peer_wire.csv | 12 +-- wire/test/run-peer-wire.c | 38 ++++----- 29 files changed, 205 insertions(+), 205 deletions(-) delete mode 100644 wire/extracted_peer_06_zeroconf.patch diff --git a/Makefile b/Makefile index 39b600335f0f..3d11b3299ba0 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ CCANDIR := ccan # Where we keep the BOLT RFCs BOLTDIR := ../bolts/ -DEFAULT_BOLTVERSION := 03468e17563650fb9bfe58b2da4d1e5d28e92009 +DEFAULT_BOLTVERSION := bc86304b4b0af5fd5ce9d24f74e2ebbceb7e2730 # Can be overridden on cmdline. BOLTVERSION := $(DEFAULT_BOLTVERSION) diff --git a/channeld/channeld.c b/channeld/channeld.c index 15aabc5b984f..9777959a6d9b 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -1,4 +1,4 @@ -/* Main channel operation daemon: runs from funding_locked to shutdown_complete. +/* Main channel operation daemon: runs from channel_ready to shutdown_complete. * * We're fairly synchronous: our main loop looks for master or * peer requests and services them synchronously. @@ -52,7 +52,7 @@ struct peer { struct per_peer_state *pps; - bool funding_locked[NUM_SIDES]; + bool channel_ready[NUM_SIDES]; u64 next_index[NUM_SIDES]; /* Features peer supports. */ @@ -182,7 +182,7 @@ struct peer { /* Penalty bases for this channel / peer. */ struct penalty_base **pbases; - /* We allow a 'tx-sigs' message between reconnect + funding_locked */ + /* We allow a 'tx-sigs' message between reconnect + channel_ready */ bool tx_sigs_allowed; /* Have we announced the real scid with a @@ -204,7 +204,7 @@ static void start_commit_timer(struct peer *peer); static void billboard_update(const struct peer *peer) { - const char *update = billboard_message(tmpctx, peer->funding_locked, + const char *update = billboard_message(tmpctx, peer->channel_ready, peer->have_sigs, peer->shutdown_sent, peer->depth_togo, @@ -539,7 +539,7 @@ static void channel_announcement_negotiate(struct peer *peer) return; /* Can't do anything until funding is locked. */ - if (!peer->funding_locked[LOCAL] || !peer->funding_locked[REMOTE]) + if (!peer->channel_ready[LOCAL] || !peer->channel_ready[REMOTE]) return; if (!peer->channel_local_active) { @@ -560,7 +560,7 @@ static void channel_announcement_negotiate(struct peer *peer) * A node: * - if the `open_channel` message has the `announce_channel` bit set AND a `shutdown` message has not been sent: * - MUST send the `announcement_signatures` message. - * - MUST NOT send `announcement_signatures` messages until `funding_locked` + * - MUST NOT send `announcement_signatures` messages until `channel_ready` * has been sent and received AND the funding transaction has at least six confirmations. * - otherwise: * - MUST NOT send the `announcement_signatures` message. @@ -570,7 +570,7 @@ static void channel_announcement_negotiate(struct peer *peer) /* BOLT #7: * - * - MUST NOT send `announcement_signatures` messages until `funding_locked` + * - MUST NOT send `announcement_signatures` messages until `channel_ready` * has been sent and received AND the funding transaction has at least six confirmations. */ if (peer->announce_depth_reached && !peer->have_sigs[LOCAL]) { @@ -602,18 +602,18 @@ static void channel_announcement_negotiate(struct peer *peer) } } -static void handle_peer_funding_locked(struct peer *peer, const u8 *msg) +static void handle_peer_channel_ready(struct peer *peer, const u8 *msg) { struct channel_id chanid; - struct tlv_funding_locked_tlvs *tlvs; + struct tlv_channel_ready_tlvs *tlvs; /* BOLT #2: * * A node: *... * - upon reconnection: - * - MUST ignore any redundant `funding_locked` it receives. + * - MUST ignore any redundant `channel_ready` it receives. */ - if (peer->funding_locked[REMOTE]) + if (peer->channel_ready[REMOTE]) return; /* Too late, we're shutting down! */ @@ -621,10 +621,10 @@ static void handle_peer_funding_locked(struct peer *peer, const u8 *msg) return; peer->old_remote_per_commit = peer->remote_per_commit; - if (!fromwire_funding_locked(msg, msg, &chanid, + if (!fromwire_channel_ready(msg, msg, &chanid, &peer->remote_per_commit, &tlvs)) peer_failed_warn(peer->pps, &peer->channel_id, - "Bad funding_locked %s", tal_hex(msg, msg)); + "Bad channel_ready %s", tal_hex(msg, msg)); if (!channel_id_eq(&chanid, &peer->channel_id)) peer_failed_err(peer->pps, &chanid, @@ -634,17 +634,17 @@ static void handle_peer_funding_locked(struct peer *peer, const u8 *msg) &peer->channel_id)); peer->tx_sigs_allowed = false; - peer->funding_locked[REMOTE] = true; - if (tlvs->alias != NULL) { + peer->channel_ready[REMOTE] = true; + if (tlvs->short_channel_id != NULL) { status_debug( "Peer told us that they'll use alias=%s for this channel", type_to_string(tmpctx, struct short_channel_id, - tlvs->alias)); - peer->short_channel_ids[REMOTE] = *tlvs->alias; + tlvs->short_channel_id)); + peer->short_channel_ids[REMOTE] = *tlvs->short_channel_id; } wire_sync_write(MASTER_FD, - take(towire_channeld_got_funding_locked( - NULL, &peer->remote_per_commit, tlvs->alias))); + take(towire_channeld_got_channel_ready( + NULL, &peer->remote_per_commit, tlvs->short_channel_id))); channel_announcement_negotiate(peer); billboard_update(peer); @@ -2119,8 +2119,8 @@ static void handle_unexpected_tx_sigs(struct peer *peer, const u8 *msg) struct bitcoin_txid txid; /* In a rare case, a v2 peer may re-send a tx_sigs message. - * This happens when they've/we've exchanged funding_locked, - * but they did not receive our funding_locked. */ + * This happens when they've/we've exchanged channel_ready, + * but they did not receive our channel_ready. */ if (!fromwire_tx_signatures(tmpctx, msg, &cid, &txid, cast_const3(struct witness_stack ***, &ws))) peer_failed_warn(peer->pps, &peer->channel_id, @@ -2212,9 +2212,9 @@ static void peer_in(struct peer *peer, const u8 *msg) if (handle_peer_error(peer->pps, &peer->channel_id, msg)) return; - /* Must get funding_locked before almost anything. */ - if (!peer->funding_locked[REMOTE]) { - if (type != WIRE_FUNDING_LOCKED + /* Must get channel_ready before almost anything. */ + if (!peer->channel_ready[REMOTE]) { + if (type != WIRE_CHANNEL_READY && type != WIRE_SHUTDOWN /* We expect these for v2 !! */ && type != WIRE_TX_SIGNATURES @@ -2228,8 +2228,8 @@ static void peer_in(struct peer *peer, const u8 *msg) } switch (type) { - case WIRE_FUNDING_LOCKED: - handle_peer_funding_locked(peer, msg); + case WIRE_CHANNEL_READY: + handle_peer_channel_ready(peer, msg); return; case WIRE_ANNOUNCEMENT_SIGNATURES: handle_peer_announcement_signatures(peer, msg); @@ -2664,7 +2664,7 @@ static void check_current_dataloss_fields(struct peer *peer, status_debug("option_data_loss_protect: fields are correct"); } -/* Older LND sometimes sends funding_locked before reestablish! */ +/* Older LND sometimes sends channel_ready before reestablish! */ /* ... or announcement_signatures. Sigh, let's handle whatever they send. */ static bool capture_premature_msg(const u8 ***shit_lnd_says, const u8 *msg) { @@ -2941,19 +2941,21 @@ static void peer_reconnect(struct peer *peer, * * - if `next_commitment_number` is 1 in both the * `channel_reestablish` it sent and received: - * - MUST retransmit `funding_locked`. + * - MUST retransmit `channel_ready`. * - otherwise: - * - MUST NOT retransmit `funding_locked`. + * - MUST NOT retransmit `channel_ready`, but MAY send + * `channel_ready` with a different `short_channel_id` + * `alias` field. */ - if (peer->funding_locked[LOCAL] + if (peer->channel_ready[LOCAL] && peer->next_index[LOCAL] == 1 && next_commitment_number == 1) { - struct tlv_funding_locked_tlvs *tlvs = tlv_funding_locked_tlvs_new(tmpctx); + struct tlv_channel_ready_tlvs *tlvs = tlv_channel_ready_tlvs_new(tmpctx); status_debug("Retransmitting funding_locked for channel %s", type_to_string(tmpctx, struct channel_id, &peer->channel_id)); /* Contains per commit point #1, for first post-opening commit */ - msg = towire_funding_locked(NULL, + msg = towire_channel_ready(NULL, &peer->channel_id, &peer->next_local_per_commit, tlvs); peer_write(peer->pps, take(msg)); @@ -3229,7 +3231,7 @@ static void handle_funding_depth(struct peer *peer, const u8 *msg) { u32 depth; struct short_channel_id *scid, *alias_local; - struct tlv_funding_locked_tlvs *tlvs; + struct tlv_channel_ready_tlvs *tlvs; struct pubkey point; if (!fromwire_channeld_funding_depth(tmpctx, @@ -3258,25 +3260,25 @@ static void handle_funding_depth(struct peer *peer, const u8 *msg) else if (alias_local) peer->short_channel_ids[LOCAL] = *alias_local; - if (!peer->funding_locked[LOCAL]) { - status_debug("funding_locked: sending commit index" + if (!peer->channel_ready[LOCAL]) { + status_debug("channel_ready: sending commit index" " %"PRIu64": %s", peer->next_index[LOCAL], type_to_string(tmpctx, struct pubkey, &peer->next_local_per_commit)); - tlvs = tlv_funding_locked_tlvs_new(tmpctx); - tlvs->alias = alias_local; + tlvs = tlv_channel_ready_tlvs_new(tmpctx); + tlvs->short_channel_id = alias_local; /* Need to retrieve the first point again, even if we - * moved on, as funding_locked explicitly includes the + * moved on, as channel_ready explicitly includes the * first one. */ get_per_commitment_point(1, &point, NULL); - msg = towire_funding_locked(NULL, &peer->channel_id, + msg = towire_channel_ready(NULL, &peer->channel_id, &point, tlvs); peer_write(peer->pps, take(msg)); - peer->funding_locked[LOCAL] = true; + peer->channel_ready[LOCAL] = true; } peer->announce_depth_reached = (depth >= ANNOUNCE_MIN_DEPTH); @@ -3310,7 +3312,7 @@ static void handle_offer_htlc(struct peer *peer, const u8 *inmsg) struct amount_sat htlc_fee; struct pubkey *blinding; - if (!peer->funding_locked[LOCAL] || !peer->funding_locked[REMOTE]) + if (!peer->channel_ready[LOCAL] || !peer->channel_ready[REMOTE]) status_failed(STATUS_FAIL_MASTER_IO, "funding not locked for offer_htlc"); @@ -3745,7 +3747,7 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNELD_SENDING_COMMITSIG_REPLY: case WIRE_CHANNELD_GOT_COMMITSIG_REPLY: case WIRE_CHANNELD_GOT_REVOKE_REPLY: - case WIRE_CHANNELD_GOT_FUNDING_LOCKED: + case WIRE_CHANNELD_GOT_CHANNEL_READY: case WIRE_CHANNELD_GOT_ANNOUNCEMENT: case WIRE_CHANNELD_GOT_SHUTDOWN: case WIRE_CHANNELD_SHUTDOWN_COMPLETE: @@ -3837,8 +3839,8 @@ static void init_channel(struct peer *peer) &peer->revocations_received, &peer->htlc_id, &htlcs, - &peer->funding_locked[LOCAL], - &peer->funding_locked[REMOTE], + &peer->channel_ready[LOCAL], + &peer->channel_ready[REMOTE], &peer->short_channel_ids[LOCAL], &reconnected, &peer->send_shutdown, diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index 31d8237a2e1d..78abd73416ae 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -53,8 +53,8 @@ msgdata,channeld_init,revocations_received,u64, msgdata,channeld_init,next_htlc_id,u64, msgdata,channeld_init,num_existing_htlcs,u16, msgdata,channeld_init,htlcs,existing_htlc,num_existing_htlcs -msgdata,channeld_init,local_funding_locked,bool, -msgdata,channeld_init,remote_funding_locked,bool, +msgdata,channeld_init,local_channel_ready,bool, +msgdata,channeld_init,remote_channel_ready,bool, msgdata,channeld_init,funding_short_id,short_channel_id, msgdata,channeld_init,reestablish,bool, msgdata,channeld_init,send_shutdown,bool, @@ -117,10 +117,10 @@ msgdata,channeld_fulfill_htlc,fulfilled_htlc,fulfilled_htlc, msgtype,channeld_fail_htlc,1006 msgdata,channeld_fail_htlc,failed_htlc,failed_htlc, -# When we receive funding_locked. -msgtype,channeld_got_funding_locked,1019 -msgdata,channeld_got_funding_locked,next_per_commit_point,pubkey, -msgdata,channeld_got_funding_locked,alias,?short_channel_id, +# When we receive channel_ready. +msgtype,channeld_got_channel_ready,1019 +msgdata,channeld_got_channel_ready,next_per_commit_point,pubkey, +msgdata,channeld_got_channel_ready,alias,?short_channel_id, #include diff --git a/closingd/closingd.c b/closingd/closingd.c index 30739e0a5486..73b22ab34343 100644 --- a/closingd/closingd.c +++ b/closingd/closingd.c @@ -260,11 +260,11 @@ receive_offer(struct per_peer_state *pps, /* BOLT #2: * * - upon reconnection: - * - MUST ignore any redundant `funding_locked` it receives. + * - MUST ignore any redundant `channel_ready` it receives. */ /* This should only happen if we've made no commitments, but * we don't have to check that: it's their problem. */ - if (fromwire_peektype(msg) == WIRE_FUNDING_LOCKED) + if (fromwire_peektype(msg) == WIRE_CHANNEL_READY) msg = tal_free(msg); /* BOLT #2: * - if it has sent a previous `shutdown`: diff --git a/common/channel_type.c b/common/channel_type.c index a2b1cab37788..07c815217c40 100644 --- a/common/channel_type.c +++ b/common/channel_type.c @@ -8,7 +8,7 @@ * arbitrary combination (they represent the persistent features which * affect the channel operation). * - * The currently defined types are: + * The currently defined basic types are: * - no features (no bits set) * - `option_static_remotekey` (bit 12) * - `option_anchor_outputs` and `option_static_remotekey` (bits 20 and 12) @@ -118,8 +118,11 @@ struct channel_type *channel_type_accept(const tal_t *ctx, OPT_ZEROCONF, }; - /* The basic channel_types can have any number of the - * following optional bits. */ + /* BOLT #2: + * Each basic type has the following variations allowed: + * - `option_scid_alias` (bit 46) + * - `option_zeroconf` (bit 50) + */ static const size_t variants[] = { OPT_ZEROCONF, }; diff --git a/common/gossip_constants.h b/common/gossip_constants.h index dac2562eb9fb..3ce395eac70e 100644 --- a/common/gossip_constants.h +++ b/common/gossip_constants.h @@ -32,7 +32,7 @@ /* BOLT #7: * - * - MUST NOT send `announcement_signatures` messages until `funding_locked` + * - MUST NOT send `announcement_signatures` messages until `channel_ready` * has been sent and received AND the funding transaction has at least six * confirmations. */ diff --git a/common/gossip_store.c b/common/gossip_store.c index 086232c2953f..2f3f329a2d2e 100644 --- a/common/gossip_store.c +++ b/common/gossip_store.c @@ -69,7 +69,7 @@ static bool public_msg_type(enum peer_wire type) case WIRE_ACCEPT_CHANNEL: case WIRE_FUNDING_CREATED: case WIRE_FUNDING_SIGNED: - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: case WIRE_OPEN_CHANNEL2: case WIRE_ACCEPT_CHANNEL2: case WIRE_INIT_RBF: diff --git a/connectd/gossip_rcvd_filter.c b/connectd/gossip_rcvd_filter.c index 13ff0a2f7c0c..7e3c72331001 100644 --- a/connectd/gossip_rcvd_filter.c +++ b/connectd/gossip_rcvd_filter.c @@ -71,7 +71,7 @@ static bool is_msg_gossip_broadcast(const u8 *cursor) case WIRE_ACCEPT_CHANNEL: case WIRE_FUNDING_CREATED: case WIRE_FUNDING_SIGNED: - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: case WIRE_SHUTDOWN: case WIRE_CLOSING_SIGNED: case WIRE_UPDATE_ADD_HTLC: diff --git a/connectd/multiplex.c b/connectd/multiplex.c index ae7f7585b73d..96a32fce017e 100644 --- a/connectd/multiplex.c +++ b/connectd/multiplex.c @@ -361,7 +361,7 @@ static bool is_urgent(enum peer_wire type) case WIRE_ACCEPT_CHANNEL: case WIRE_FUNDING_CREATED: case WIRE_FUNDING_SIGNED: - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: case WIRE_OPEN_CHANNEL2: case WIRE_ACCEPT_CHANNEL2: case WIRE_INIT_RBF: diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 55321e1dbce2..8c42eec96bc7 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -529,7 +529,7 @@ static void handle_recv_gossip(struct daemon *daemon, const u8 *outermsg) case WIRE_ACCEPT_CHANNEL: case WIRE_FUNDING_CREATED: case WIRE_FUNDING_SIGNED: - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: case WIRE_SHUTDOWN: case WIRE_CLOSING_SIGNED: case WIRE_UPDATE_ADD_HTLC: diff --git a/lightningd/channel.c b/lightningd/channel.c index fbf1f4ba8f95..8a35558c0502 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -221,7 +221,7 @@ struct channel *new_unsaved_channel(struct peer *peer, channel->open_attempt = NULL; channel->last_htlc_sigs = NULL; - channel->remote_funding_locked = false; + channel->remote_channel_ready = false; channel->scid = NULL; channel->next_index[LOCAL] = 1; channel->next_index[REMOTE] = 1; @@ -345,7 +345,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, struct amount_sat funding_sats, struct amount_msat push, struct amount_sat our_funds, - bool remote_funding_locked, + bool remote_channel_ready, /* NULL or stolen */ struct short_channel_id *scid, struct short_channel_id *alias_local STEALS, @@ -441,7 +441,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, channel->funding_sats = funding_sats; channel->push = push; channel->our_funds = our_funds; - channel->remote_funding_locked = remote_funding_locked; + channel->remote_channel_ready = remote_channel_ready; channel->scid = tal_steal(channel, scid); channel->alias[LOCAL] = tal_steal(channel, alias_local); channel->alias[REMOTE] = tal_steal(channel, alias_remote); /* Haven't gotten one yet. */ diff --git a/lightningd/channel.h b/lightningd/channel.h index eba34ffa0836..a971b012e42f 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -138,7 +138,7 @@ struct channel { struct amount_sat our_funds; struct amount_msat push; - bool remote_funding_locked; + bool remote_channel_ready; /* Channel if locked locally. */ struct short_channel_id *scid; @@ -291,7 +291,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, struct amount_sat funding_sats, struct amount_msat push, struct amount_sat our_funds, - bool remote_funding_locked, + bool remote_channel_ready, /* NULL or stolen */ struct short_channel_id *scid STEALS, struct short_channel_id *alias_local STEALS, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 8d2cbb24457e..5d4873d8c5ad 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -195,7 +195,7 @@ static void lockin_complete(struct channel *channel) } /* We set this once they're locked in. */ - assert(channel->remote_funding_locked); + assert(channel->remote_channel_ready); /* We might have already started shutting down */ if (channel->state != CHANNELD_AWAITING_LOCKIN) { @@ -225,41 +225,37 @@ static void lockin_complete(struct channel *channel) true); } -bool channel_on_funding_locked(struct channel *channel, - struct pubkey *next_per_commitment_point) +bool channel_on_channel_ready(struct channel *channel, + struct pubkey *next_per_commitment_point) { - if (channel->remote_funding_locked) { + if (channel->remote_channel_ready) { channel_internal_error(channel, - "channel_got_funding_locked twice"); + "channel_got_channel_ready twice"); return false; } update_per_commit_point(channel, next_per_commitment_point); - log_debug(channel->log, "Got funding_locked"); - channel->remote_funding_locked = true; + log_debug(channel->log, "Got channel_ready"); + channel->remote_channel_ready = true; return true; } -/* We were informed by channeld that it announced the channel and sent - * an update, so we can now start sending a node_announcement. The - * first step is to build the provisional announcement and ask the HSM - * to sign it. */ - -static void peer_got_funding_locked(struct channel *channel, const u8 *msg) +/* We were informed by channeld that channel is ready (reached mindepth) */ +static void peer_got_channel_ready(struct channel *channel, const u8 *msg) { struct pubkey next_per_commitment_point; struct short_channel_id *alias_remote; - if (!fromwire_channeld_got_funding_locked(tmpctx, + if (!fromwire_channeld_got_channel_ready(tmpctx, msg, &next_per_commitment_point, &alias_remote)) { channel_internal_error(channel, - "bad channel_got_funding_locked %s", + "bad channel_got_channel_ready %s", tal_hex(channel, msg)); return; } - if (!channel_on_funding_locked(channel, &next_per_commitment_point)) + if (!channel_on_channel_ready(channel, &next_per_commitment_point)) return; if (channel->alias[REMOTE] == NULL) @@ -538,8 +534,8 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNELD_GOT_REVOKE: peer_got_revoke(sd->channel, msg); break; - case WIRE_CHANNELD_GOT_FUNDING_LOCKED: - peer_got_funding_locked(sd->channel, msg); + case WIRE_CHANNELD_GOT_CHANNEL_READY: + peer_got_channel_ready(sd->channel, msg); break; case WIRE_CHANNELD_GOT_ANNOUNCEMENT: peer_got_announcement(sd->channel, msg); @@ -765,7 +761,7 @@ bool peer_start_channeld(struct channel *channel, channel->next_htlc_id, htlcs, channel->scid != NULL, - channel->remote_funding_locked, + channel->remote_channel_ready, &scid, reconnected, /* Anything that indicates we are or have @@ -859,12 +855,11 @@ bool channel_tell_depth(struct lightningd *ld, take(towire_channeld_funding_depth( NULL, channel->scid, channel->alias[LOCAL], depth))); - if (channel->remote_funding_locked && - channel->state == CHANNELD_AWAITING_LOCKIN && - depth >= channel->minimum_depth) + if (channel->remote_channel_ready && + channel->state == CHANNELD_AWAITING_LOCKIN && + depth >= channel->minimum_depth) { lockin_complete(channel); - - else if (depth == 1 && channel->minimum_depth == 0) { + } else if (depth == 1 && channel->minimum_depth == 0) { /* If we have a zeroconf channel, i.e., no scid yet * but have exchange `channel_ready` messages, then we * need to fire a second time, in order to trigger the diff --git a/lightningd/channel_control.h b/lightningd/channel_control.h index 9008bed1d055..2f8b356e863d 100644 --- a/lightningd/channel_control.h +++ b/lightningd/channel_control.h @@ -30,9 +30,9 @@ void channel_notify_new_block(struct lightningd *ld, struct command_result *cancel_channel_before_broadcast(struct command *cmd, struct peer *peer); -/* Update the channel info on funding locked */ -bool channel_on_funding_locked(struct channel *channel, - struct pubkey *next_per_commitment_point); +/* Update the channel info on channel_ready */ +bool channel_on_channel_ready(struct channel *channel, + struct pubkey *next_per_commitment_point); /* Record channel open (coin movement notifications) */ void channel_record_open(struct channel *channel, u32 blockheight, bool record_push); diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index fa458bca3a35..a2f84ee61da0 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -1631,7 +1631,7 @@ static void handle_peer_tx_sigs_sent(struct subd *dualopend, &channel->peer->id, &channel->funding_sats, &channel->funding.txid, - channel->remote_funding_locked); + channel->remote_channel_ready); /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2 * The receiving node: ... @@ -1714,7 +1714,7 @@ static void handle_peer_locked(struct subd *dualopend, const u8 *msg) /* Updates channel with the next per-commit point etc, calls * channel_internal_error on failure */ - if (!channel_on_funding_locked(channel, &remote_per_commit)) + if (!channel_on_channel_ready(channel, &remote_per_commit)) return; /* Remember that we got the lock-in */ @@ -1737,7 +1737,7 @@ static void handle_channel_locked(struct subd *dualopend, peer_fd = new_peer_fd_arr(tmpctx, fds); assert(channel->scid); - assert(channel->remote_funding_locked); + assert(channel->remote_channel_ready); /* This can happen if we missed their sigs, for some reason */ if (channel->state != DUALOPEND_AWAITING_LOCKIN) @@ -1997,7 +1997,7 @@ static void handle_peer_tx_sigs_msg(struct subd *dualopend, &channel->peer->id, &channel->funding_sats, &channel->funding.txid, - channel->remote_funding_locked); + channel->remote_channel_ready); /* BOLT-f53ca2301232db780843e894f55d95d512f297f9 #2 * The receiving node: ... @@ -3364,10 +3364,14 @@ bool peer_start_dualopend(struct peer *peer, /* BOLT #2: * * The sender: - * - SHOULD set `minimum_depth` to a number of blocks it - * considers reasonable to avoid double-spending of the - * funding transaction. + * - if `channel_type` includes `option_zeroconf`: + * - MUST set `minimum_depth` to zero. + * - otherwise: + * - SHOULD set `minimum_depth` to a number of blocks it + * considers reasonable to avoid double-spending of the + * funding transaction. */ + /* FIXME: We should override this to 0 in the openchannel2 hook of we want zeroconf*/ channel->minimum_depth = peer->ld->config.anchor_confirms; msg = towire_dualopend_init(NULL, chainparams, @@ -3470,7 +3474,7 @@ bool peer_restart_dualopend(struct peer *peer, inflight->funding_psbt, channel->opener, channel->scid != NULL, - channel->remote_funding_locked, + channel->remote_channel_ready, channel->state == CHANNELD_SHUTTING_DOWN, channel->shutdown_scriptpubkey[REMOTE] != NULL, channel->shutdown_scriptpubkey[LOCAL], diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index 4eb634cfeb81..232dc2a11dae 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -625,7 +625,7 @@ enum watch_result onchaind_funding_spent(struct channel *channel, channel_fail_permanent(channel, reason, "Funding transaction spent"); /* If we haven't posted the open event yet, post an open */ - if (!channel->scid || !channel->remote_funding_locked) { + if (!channel->scid || !channel->remote_channel_ready) { u32 blkh; /* Blockheight will be zero if it's not in chain */ blkh = wallet_transaction_height(channel->peer->ld->wallet, diff --git a/lightningd/opening_common.c b/lightningd/opening_common.c index 778648b0a55b..5f2f848d8c83 100644 --- a/lightningd/opening_common.c +++ b/lightningd/opening_common.c @@ -55,9 +55,14 @@ new_uncommitted_channel(struct peer *peer) /* BOLT #2: * * The sender: - * - SHOULD set `minimum_depth` to a number of blocks it considers - * reasonable to avoid double-spending of the funding transaction. + * - if `channel_type` includes `option_zeroconf`: + * - MUST set `minimum_depth` to zero. + * - otherwise: + * - SHOULD set `minimum_depth` to a number of blocks it + * considers reasonable to avoid double-spending of the + * funding transaction. */ + /* We override this in openchannel hook if we want zeroconf */ uc->minimum_depth = ld->config.anchor_confirms; /* Declare the new channel to the HSM. */ diff --git a/lightningd/opening_control.c b/lightningd/opening_control.c index 3e740844c3f5..f059a7eb7200 100644 --- a/lightningd/opening_control.c +++ b/lightningd/opening_control.c @@ -178,7 +178,7 @@ wallet_commit_channel(struct lightningd *ld, funding_sats, push, local_funding, - false, /* !remote_funding_locked */ + false, /* !remote_channel_ready */ NULL, /* no scid yet */ alias_local, /* But maybe we have an alias we want to use? */ NULL, /* They haven't told us an alias yet */ @@ -539,7 +539,7 @@ static void opening_fundee_finished(struct subd *openingd, /* Tell plugins about the success */ notify_channel_opened(ld, &channel->peer->id, &channel->funding_sats, - &channel->funding.txid, channel->remote_funding_locked); + &channel->funding.txid, channel->remote_channel_ready); if (pbase) wallet_penalty_base_add(ld->wallet, channel->dbid, pbase); @@ -1213,8 +1213,12 @@ static struct command_result *json_fundchannel_start(struct command *cmd, /* BOLT #2: * * The sender: - * - SHOULD set `minimum_depth` to a number of blocks it considers - * reasonable to avoid double-spending of the funding transaction. + * - if `channel_type` includes `option_zeroconf`: + * - MUST set `minimum_depth` to zero. + * - otherwise: + * - SHOULD set `minimum_depth` to a number of blocks it + * considers reasonable to avoid double-spending of the + * funding transaction. */ assert(mindepth != NULL); fc->uc->minimum_depth = *mindepth; @@ -1376,7 +1380,7 @@ static struct channel *stub_chan(struct command *cmd, funding_sats, AMOUNT_MSAT(0), AMOUNT_SAT(0), - true, /* !remote_funding_locked */ + true, /* remote_channel_ready */ scid, scid, scid, diff --git a/openingd/dualopend.c b/openingd/dualopend.c index c2de0716b3ff..0c40c0fdc6aa 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -195,7 +195,7 @@ struct state { struct feature_set *our_features; /* Tally of which sides are locked, or not */ - bool funding_locked[NUM_SIDES]; + bool channel_ready[NUM_SIDES]; /* Are we shutting down? */ bool shutdown_sent[NUM_SIDES]; @@ -380,7 +380,7 @@ static void negotiation_failed(struct state *state, static void billboard_update(struct state *state) { - const char *update = billboard_message(tmpctx, state->funding_locked, + const char *update = billboard_message(tmpctx, state->channel_ready, NULL, state->shutdown_sent, 0, /* Always zero? */ @@ -930,9 +930,9 @@ static void handle_tx_sigs(struct state *state, const u8 *msg) open_err_fatal(state, "Bad tx_signatures %s", tal_hex(msg, msg)); - /* Maybe they didn't get our funding_locked message ? */ - if (state->funding_locked[LOCAL] && !state->reconnected) { - status_broken("Got WIRE_TX_SIGNATURES after funding locked " + /* Maybe they didn't get our channel_ready message ? */ + if (state->channel_ready[LOCAL] && !state->reconnected) { + status_broken("Got WIRE_TX_SIGNATURES after channel_ready " "for channel %s, ignoring: %s", type_to_string(tmpctx, struct channel_id, &state->channel_id), @@ -941,10 +941,10 @@ static void handle_tx_sigs(struct state *state, const u8 *msg) } /* On reconnect, we expect them to resend tx_sigs if they haven't - * gotten our funding_locked yet */ - if (state->funding_locked[REMOTE] && !state->reconnected) + * gotten our channel_ready yet */ + if (state->channel_ready[REMOTE] && !state->reconnected) open_err_warn(state, - "tx_signatures sent after funding_locked %s", + "tx_signatures sent after channel_ready %s", tal_hex(msg, msg)); if (!tx_state->psbt) @@ -1128,18 +1128,18 @@ static void init_changeset(struct tx_state *tx_state, struct wally_psbt *psbt) tx_state->changeset = psbt_get_changeset(tx_state, empty_psbt, psbt); } -static u8 *handle_funding_locked(struct state *state, u8 *msg) +static u8 *handle_channel_ready(struct state *state, u8 *msg) { struct channel_id cid; struct pubkey remote_per_commit; - struct tlv_funding_locked_tlvs *tlvs; + struct tlv_channel_ready_tlvs *tlvs; - if (!fromwire_funding_locked(tmpctx, msg, &cid, &remote_per_commit, &tlvs)) - open_err_fatal(state, "Bad funding_locked %s", + if (!fromwire_channel_ready(tmpctx, msg, &cid, &remote_per_commit, &tlvs)) + open_err_fatal(state, "Bad channel_ready %s", tal_hex(msg, msg)); if (!channel_id_eq(&cid, &state->channel_id)) - open_err_fatal(state, "funding_locked ids don't match:" + open_err_fatal(state, "channel_ready ids don't match:" " expected %s, got %s", type_to_string(msg, struct channel_id, &state->channel_id), @@ -1148,21 +1148,21 @@ static u8 *handle_funding_locked(struct state *state, u8 *msg) /* If we haven't gotten their tx_sigs yet, this is a protocol error */ if (!state->tx_state->remote_funding_sigs_rcvd) { open_err_warn(state, - "funding_locked sent before tx_signatures %s", + "channel_ready sent before tx_signatures %s", tal_hex(msg, msg)); } /* We save when the peer locks, so we do the right * thing on reconnects */ - if (!state->funding_locked[REMOTE]) { + if (!state->channel_ready[REMOTE]) { msg = towire_dualopend_peer_locked(NULL, &remote_per_commit); wire_sync_write(REQ_FD, take(msg)); } - state->funding_locked[REMOTE] = true; + state->channel_ready[REMOTE] = true; billboard_update(state); - if (state->funding_locked[LOCAL]) + if (state->channel_ready[LOCAL]) return towire_dualopend_channel_locked(state); return NULL; @@ -1247,8 +1247,8 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state) * startup an RBF */ handle_tx_sigs(state, msg); continue; - case WIRE_FUNDING_LOCKED: - handle_funding_locked(state, msg); + case WIRE_CHANNEL_READY: + handle_channel_ready(state, msg); return NULL; case WIRE_SHUTDOWN: handle_peer_shutdown(state, msg); @@ -1608,7 +1608,7 @@ static bool run_tx_interactive(struct state *state, case WIRE_ACCEPT_CHANNEL: case WIRE_FUNDING_CREATED: case WIRE_FUNDING_SIGNED: - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: case WIRE_SHUTDOWN: case WIRE_CLOSING_SIGNED: case WIRE_UPDATE_ADD_HTLC: @@ -3388,19 +3388,19 @@ static void hsm_per_commitment_point(u64 index, struct pubkey *point) tal_hex(tmpctx, msg)); } -static void send_funding_locked(struct state *state) +static void send_channel_ready(struct state *state) { u8 *msg; struct pubkey next_local_per_commit; - struct tlv_funding_locked_tlvs *tlvs = tlv_funding_locked_tlvs_new(tmpctx); + struct tlv_channel_ready_tlvs *tlvs = tlv_channel_ready_tlvs_new(tmpctx); /* Figure out the next local commit */ hsm_per_commitment_point(1, &next_local_per_commit); - msg = towire_funding_locked(NULL, &state->channel_id, + msg = towire_channel_ready(NULL, &state->channel_id, &next_local_per_commit, tlvs); peer_write(state->pps, take(msg)); - state->funding_locked[LOCAL] = true; + state->channel_ready[LOCAL] = true; billboard_update(state); } @@ -3453,8 +3453,8 @@ static u8 *handle_funding_depth(struct state *state, u8 *msg) /* Tell gossipd the new channel exists before we tell peer. */ tell_gossipd_new_channel(state); - send_funding_locked(state); - if (state->funding_locked[REMOTE]) + send_channel_ready(state); + if (state->channel_ready[REMOTE]) return towire_dualopend_channel_locked(state); return NULL; @@ -3614,17 +3614,17 @@ static void do_reconnect_dance(struct state *state) /* It's possible we sent our sigs, but they didn't get them. * Resend our signatures, just in case */ if (psbt_side_finalized(tx_state->psbt, state->our_role) - && !state->funding_locked[REMOTE]) { + && !state->channel_ready[REMOTE]) { msg = psbt_to_tx_sigs_msg(NULL, state, tx_state->psbt); peer_write(state->pps, take(msg)); } - if (state->funding_locked[LOCAL]) { + if (state->channel_ready[LOCAL]) { status_debug("Retransmitting funding_locked for channel %s", type_to_string(tmpctx, struct channel_id, &state->channel_id)); - send_funding_locked(state); + send_channel_ready(state); } peer_billboard(true, "Reconnected, and reestablished."); @@ -3714,8 +3714,8 @@ static u8 *handle_peer_in(struct state *state) case WIRE_TX_SIGNATURES: handle_tx_sigs(state, msg); return NULL; - case WIRE_FUNDING_LOCKED: - return handle_funding_locked(state, msg); + case WIRE_CHANNEL_READY: + return handle_channel_ready(state, msg); case WIRE_SHUTDOWN: handle_peer_shutdown(state, msg); return NULL; @@ -3833,8 +3833,8 @@ int main(int argc, char *argv[]) = NULL; /*~ We're not locked or shutting down quite yet */ - state->funding_locked[LOCAL] - = state->funding_locked[REMOTE] + state->channel_ready[LOCAL] + = state->channel_ready[REMOTE] = false; state->shutdown_sent[LOCAL] = state->shutdown_sent[REMOTE] @@ -3861,8 +3861,8 @@ int main(int argc, char *argv[]) &state->first_per_commitment_point[REMOTE], &state->tx_state->psbt, &opener, - &state->funding_locked[LOCAL], - &state->funding_locked[REMOTE], + &state->channel_ready[LOCAL], + &state->channel_ready[REMOTE], &state->shutdown_sent[LOCAL], &state->shutdown_sent[REMOTE], &state->upfront_shutdown_script[LOCAL], diff --git a/openingd/openingd.c b/openingd/openingd.c index d2ae1cada07f..3e9272a43f8d 100644 --- a/openingd/openingd.c +++ b/openingd/openingd.c @@ -839,8 +839,9 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg) /* BOLT #2: * The receiving node MUST fail the channel if: *... - * - It supports `channel_type`, `channel_type` was set, and the - * `type` is not suitable. + * - It supports `channel_type` and `channel_type` was set: + * - if `type` is not suitable. + * - if `type` includes `option_zeroconf` and it does not trust the sender to open an unconfirmed channel. */ if (open_tlvs->channel_type) { state->channel_type = diff --git a/tests/test_closing.py b/tests/test_closing.py index e2cf90dac9f0..f278d9c93a19 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -1785,7 +1785,7 @@ def test_onchain_first_commit(node_factory, bitcoind): coin_mvt_plugin = os.path.join(os.getcwd(), 'tests/plugins/coin_movements.py') # HTLC 1->2, 1 fails just after funding. - disconnects = ['+WIRE_FUNDING_LOCKED', 'permfail'] + disconnects = ['+WIRE_CHANNEL_READY', 'permfail'] # Make locktime different, as we once had them reversed! l1, l2 = node_factory.line_graph(2, opts=[{'disconnect': disconnects, 'plugin': coin_mvt_plugin}, diff --git a/tests/test_connection.py b/tests/test_connection.py index 906e8c80cd0f..3f915c8c6fb4 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -679,7 +679,7 @@ def test_reconnect_no_update(node_factory, executor, bitcoind): reconnects. See comments for details. """ - disconnects = ["-WIRE_FUNDING_LOCKED", "-WIRE_SHUTDOWN"] + disconnects = ["-WIRE_CHANNEL_READY", "-WIRE_SHUTDOWN"] # Allow bad gossip because it might receive WIRE_CHANNEL_UPDATE before # announcement of the disconnection l1 = node_factory.get_node(may_reconnect=True, allow_bad_gossip=True) @@ -715,8 +715,8 @@ def test_reconnect_no_update(node_factory, executor, bitcoind): @pytest.mark.openchannel('v2') def test_reconnect_normal(node_factory): # Should reconnect fine even if locked message gets lost. - disconnects = ['-WIRE_FUNDING_LOCKED', - '+WIRE_FUNDING_LOCKED'] + disconnects = ['-WIRE_CHANNEL_READY', + '+WIRE_CHANNEL_READY'] l1 = node_factory.get_node(disconnect=disconnects, may_reconnect=True) l2 = node_factory.get_node(may_reconnect=True) @@ -2234,7 +2234,7 @@ def test_channel_persistence(node_factory, bitcoind, executor): # Fire off a sendpay request, it'll get interrupted by a restart executor.submit(l1.pay, l2, 10000) # Wait for it to be committed to, i.e., stored in the DB - l1.daemon.wait_for_log('peer_in WIRE_FUNDING_LOCKED') + l1.daemon.wait_for_log('peer_in WIRE_CHANNEL_READY') l1.daemon.wait_for_log('peer_in WIRE_COMMITMENT_SIGNED') # Stop l2, l1 will reattempt to connect diff --git a/tests/test_opening.py b/tests/test_opening.py index abbdac3658d8..7072e82165d4 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -1274,13 +1274,13 @@ def test_zeroconf_mindepth(bitcoind, node_factory): assert l2.db.query('SELECT minimum_depth FROM channels') == [{'minimum_depth': 2}] bitcoind.generate_block(2, wait_for_mempool=1) # Confirm on the l2 side. - l2.daemon.wait_for_log(r'peer_out WIRE_FUNDING_LOCKED') + l2.daemon.wait_for_log(r'peer_out WIRE_CHANNEL_READY') # l1 should not be sending funding_locked/channel_ready yet, it is # configured to wait for 6 confirmations. - assert not l1.daemon.is_in_log(r'peer_out WIRE_FUNDING_LOCKED') + assert not l1.daemon.is_in_log(r'peer_out WIRE_CHANNEL_READY') bitcoind.generate_block(4) # Confirm on the l2 side. - l1.daemon.wait_for_log(r'peer_out WIRE_FUNDING_LOCKED') + l1.daemon.wait_for_log(r'peer_out WIRE_CHANNEL_READY') wait_for(lambda: l1.rpc.listpeers()['peers'][0]['channels'][0]['state'] == "CHANNELD_NORMAL") wait_for(lambda: l2.rpc.listpeers()['peers'][0]['channels'][0]['state'] == "CHANNELD_NORMAL") @@ -1318,11 +1318,11 @@ def test_zeroconf_open(bitcoind, node_factory): assert l2.db.query('SELECT minimum_depth FROM channels') == [{'minimum_depth': 0}] l1.daemon.wait_for_logs([ - r'peer_in WIRE_FUNDING_LOCKED', + r'peer_in WIRE_CHANNEL_READY', r'Peer told us that they\'ll use alias=[0-9x]+ for this channel', ]) l2.daemon.wait_for_logs([ - r'peer_in WIRE_FUNDING_LOCKED', + r'peer_in WIRE_CHANNEL_READY', r'Peer told us that they\'ll use alias=[0-9x]+ for this channel', ]) @@ -1606,8 +1606,8 @@ def test_zeroconf_multichan_forward(node_factory): l2.fundwallet(10**7) l2.rpc.fundchannel(l3.info['id'], 2 * 10**6, mindepth=0) - l2.daemon.wait_for_log(r'peer_in WIRE_FUNDING_LOCKED') - l3.daemon.wait_for_log(r'peer_in WIRE_FUNDING_LOCKED') + l2.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_READY') + l3.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_READY') inv = l3.rpc.invoice(amount_msat=10000, label='lbl1', description='desc')['bolt11'] l1.rpc.pay(inv) diff --git a/wallet/wallet.c b/wallet/wallet.c index 9cc9e8e58caa..8ba81f9ffa73 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1922,7 +1922,7 @@ void wallet_channel_save(struct wallet *w, struct channel *chan) db_bind_int(stmt, 11, chan->funding.n); db_bind_amount_sat(stmt, 12, &chan->funding_sats); db_bind_amount_sat(stmt, 13, &chan->our_funds); - db_bind_int(stmt, 14, chan->remote_funding_locked); + db_bind_int(stmt, 14, chan->remote_channel_ready); db_bind_amount_msat(stmt, 15, &chan->push); db_bind_amount_msat(stmt, 16, &chan->our_msat); diff --git a/wire/extracted_peer_03_openchannelv2.patch b/wire/extracted_peer_03_openchannelv2.patch index c32c95529883..81b5ce8cfce0 100644 --- a/wire/extracted_peer_03_openchannelv2.patch +++ b/wire/extracted_peer_03_openchannelv2.patch @@ -42,9 +42,9 @@ msgdata,open_channel,chain_hash,chain_hash, msgdata,open_channel,temporary_channel_id,byte,32 @@ -86,6 +116,56 @@ - msgtype,funding_locked,36 - msgdata,funding_locked,channel_id,channel_id, - msgdata,funding_locked,next_per_commitment_point,point, + msgdata,channel_ready,tlvs,channel_ready_tlvs, + tlvtype,channel_ready_tlvs,short_channel_id,1 + tlvdata,channel_ready_tlvs,short_channel_id,alias,short_channel_id, +msgtype,open_channel2,64 +msgdata,open_channel2,chain_hash,chain_hash, +msgdata,open_channel2,channel_id,channel_id, diff --git a/wire/extracted_peer_06_zeroconf.patch b/wire/extracted_peer_06_zeroconf.patch deleted file mode 100644 index 5084b00cb7e3..000000000000 --- a/wire/extracted_peer_06_zeroconf.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/wire/peer_wire.csv b/wire/peer_wire.csv -index a028ddc66..fc24b61ef 100644 ---- a/wire/peer_wire.csv -+++ b/wire/peer_wire.csv -@@ -126,6 +126,9 @@ msgdata,funding_signed,signature,signature, - msgtype,funding_locked,36 - msgdata,funding_locked,channel_id,channel_id, - msgdata,funding_locked,next_per_commitment_point,point, -+msgdata,funding_locked,tlvs,funding_locked_tlvs, -+tlvtype,funding_locked_tlvs,alias,1 -+tlvdata,funding_locked_tlvs,alias,scid,short_channel_id, - msgtype,open_channel2,64 - msgdata,open_channel2,chain_hash,chain_hash, - msgdata,open_channel2,channel_id,channel_id, diff --git a/wire/peer_wire.c b/wire/peer_wire.c index 0aca55a5d488..2bd0eea71119 100644 --- a/wire/peer_wire.c +++ b/wire/peer_wire.c @@ -12,7 +12,7 @@ static bool unknown_type(enum peer_wire t) case WIRE_ACCEPT_CHANNEL: case WIRE_FUNDING_CREATED: case WIRE_FUNDING_SIGNED: - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: case WIRE_SHUTDOWN: case WIRE_CLOSING_SIGNED: case WIRE_UPDATE_ADD_HTLC: @@ -75,7 +75,7 @@ bool is_msg_for_gossipd(const u8 *cursor) case WIRE_ACCEPT_CHANNEL: case WIRE_FUNDING_CREATED: case WIRE_FUNDING_SIGNED: - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: case WIRE_SHUTDOWN: case WIRE_CLOSING_SIGNED: case WIRE_UPDATE_ADD_HTLC: @@ -242,9 +242,9 @@ bool extract_channel_id(const u8 *in_pkt, struct channel_id *channel_id) * 2. data: * * [`channel_id`:`channel_id`] */ - case WIRE_FUNDING_LOCKED: + case WIRE_CHANNEL_READY: /* BOLT #2: - * 1. type: 36 (`funding_locked`) + * 1. type: 36 (`channel_ready`) * 2. data: * * [`channel_id`:`channel_id`] */ diff --git a/wire/peer_wire.csv b/wire/peer_wire.csv index d400da1b8a67..54f48115666a 100644 --- a/wire/peer_wire.csv +++ b/wire/peer_wire.csv @@ -123,12 +123,12 @@ msgdata,funding_created,signature,signature, msgtype,funding_signed,35 msgdata,funding_signed,channel_id,channel_id, msgdata,funding_signed,signature,signature, -msgtype,funding_locked,36 -msgdata,funding_locked,channel_id,channel_id, -msgdata,funding_locked,next_per_commitment_point,point, -msgdata,funding_locked,tlvs,funding_locked_tlvs, -tlvtype,funding_locked_tlvs,alias,1 -tlvdata,funding_locked_tlvs,alias,scid,short_channel_id, +msgtype,channel_ready,36 +msgdata,channel_ready,channel_id,channel_id, +msgdata,channel_ready,second_per_commitment_point,point, +msgdata,channel_ready,tlvs,channel_ready_tlvs, +tlvtype,channel_ready_tlvs,short_channel_id,1 +tlvdata,channel_ready_tlvs,short_channel_id,alias,short_channel_id, msgtype,open_channel2,64 msgdata,open_channel2,chain_hash,chain_hash, msgdata,open_channel2,channel_id,channel_id, diff --git a/wire/test/run-peer-wire.c b/wire/test/run-peer-wire.c index 1be1c016b93f..d9df608b812b 100644 --- a/wire/test/run-peer-wire.c +++ b/wire/test/run-peer-wire.c @@ -157,10 +157,10 @@ struct msg_channel_update_opt_htlc_max { struct bitcoin_blkid chain_hash; struct short_channel_id short_channel_id; }; -struct msg_funding_locked { +struct msg_channel_ready { struct channel_id channel_id; struct pubkey next_per_commitment_point; - struct tlv_funding_locked_tlvs *tlvs; + struct tlv_channel_ready_tlvs *tlvs; }; struct msg_announcement_signatures { struct channel_id channel_id; @@ -477,20 +477,20 @@ static struct msg_channel_update_opt_htlc_max return tal_free(s); } -static void *towire_struct_funding_locked(const tal_t *ctx, - const struct msg_funding_locked *s) +static void *towire_struct_channel_ready(const tal_t *ctx, + const struct msg_channel_ready *s) { - return towire_funding_locked(ctx, + return towire_channel_ready(ctx, &s->channel_id, &s->next_per_commitment_point, s->tlvs); } -static struct msg_funding_locked *fromwire_struct_funding_locked(const tal_t *ctx, const void *p) +static struct msg_channel_ready *fromwire_struct_channel_ready(const tal_t *ctx, const void *p) { - struct msg_funding_locked *s = tal(ctx, struct msg_funding_locked); + struct msg_channel_ready *s = tal(ctx, struct msg_channel_ready); - if (fromwire_funding_locked(ctx, + if (fromwire_channel_ready(ctx, p, &s->channel_id, &s->next_per_commitment_point, @@ -816,13 +816,13 @@ static bool channel_announcement_eq(const struct msg_channel_announcement *a, && eq_between(a, b, bitcoin_key_1, bitcoin_key_2); } -static bool funding_locked_eq(const struct msg_funding_locked *a, - const struct msg_funding_locked *b) +static bool channel_ready_eq(const struct msg_channel_ready *a, + const struct msg_channel_ready *b) { if (!eq_upto(a, b, tlvs)) return false; - return eq_tlv(a, b, alias, short_channel_id_eq); + return eq_tlv(a, b, short_channel_id, short_channel_id_eq); } static bool announcement_signatures_eq(const struct msg_announcement_signatures *a, @@ -1009,7 +1009,7 @@ static bool node_announcement_eq(const struct msg_node_announcement *a, int main(int argc, char *argv[]) { struct msg_channel_announcement ca, *ca2; - struct msg_funding_locked fl, *fl2; + struct msg_channel_ready fl, *fl2; struct msg_announcement_signatures as, *as2; struct msg_update_fail_htlc ufh, *ufh2; struct msg_commitment_signed cs, *cs2; @@ -1048,15 +1048,15 @@ int main(int argc, char *argv[]) test_corruption(&ca, ca2, channel_announcement); memset(&fl, 2, sizeof(fl)); - fl.tlvs = tlv_funding_locked_tlvs_new(ctx); - fl.tlvs->alias = tal(ctx, struct short_channel_id); - set_scid(fl.tlvs->alias); + fl.tlvs = tlv_channel_ready_tlvs_new(ctx); + fl.tlvs->short_channel_id = tal(ctx, struct short_channel_id); + set_scid(fl.tlvs->short_channel_id); set_pubkey(&fl.next_per_commitment_point); - msg = towire_struct_funding_locked(ctx, &fl); - fl2 = fromwire_struct_funding_locked(ctx, msg); - assert(funding_locked_eq(&fl, fl2)); - test_corruption_tlv(&fl, fl2, funding_locked); + msg = towire_struct_channel_ready(ctx, &fl); + fl2 = fromwire_struct_channel_ready(ctx, msg); + assert(channel_ready_eq(&fl, fl2)); + test_corruption_tlv(&fl, fl2, channel_ready); memset(&as, 2, sizeof(as)); From cbb569e5ba4f41b540f363b446462635797eade3 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:41:31 +0930 Subject: [PATCH 17/20] channeld/dualopend/lightningd: use channel_ready everywhere. This alters the billboard, but that's a human-readable thing so not noted in CHANGELOG. Signed-off-by: Rusty Russell Changelog-Changed: JSON-RPC: `listpeers` `status` now refers to "channel ready" rather than "funding locked" (BOLT language change for zeroconf channels) Changelog-Added: JSON-RPC: `channel_opened` notification `channel_ready` flag. Changelog-Deprecated: JSON-RPC: `channel_opened` notification `funding_locked` flag (use `channel_ready`: BOLTs namechange). --- channeld/channeld.c | 2 +- common/billboard.c | 18 +++++++++--------- common/billboard.h | 2 +- doc/PLUGINS.md | 2 +- lightningd/dual_open_control.c | 2 +- lightningd/notification.c | 10 ++++++---- lightningd/notification.h | 2 +- openingd/dualopend.c | 2 +- openingd/dualopend_wire.csv | 4 ++-- tests/test_closing.py | 6 +++--- tests/test_connection.py | 14 +++++++------- tests/test_misc.py | 6 +++--- tests/test_opening.py | 2 +- 13 files changed, 37 insertions(+), 35 deletions(-) diff --git a/channeld/channeld.c b/channeld/channeld.c index 9777959a6d9b..541f9460cd36 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -2952,7 +2952,7 @@ static void peer_reconnect(struct peer *peer, && next_commitment_number == 1) { struct tlv_channel_ready_tlvs *tlvs = tlv_channel_ready_tlvs_new(tmpctx); - status_debug("Retransmitting funding_locked for channel %s", + status_debug("Retransmitting channel_ready for channel %s", type_to_string(tmpctx, struct channel_id, &peer->channel_id)); /* Contains per commit point #1, for first post-opening commit */ msg = towire_channel_ready(NULL, diff --git a/common/billboard.c b/common/billboard.c index 5a1e62542b58..e67efe4a0ff1 100644 --- a/common/billboard.c +++ b/common/billboard.c @@ -4,7 +4,7 @@ #include char *billboard_message(const tal_t *ctx, - const bool funding_locked[NUM_SIDES], + const bool channel_ready[NUM_SIDES], const bool have_sigs[NUM_SIDES], const bool shutdown_sent[NUM_SIDES], u32 depth_togo, @@ -13,17 +13,17 @@ char *billboard_message(const tal_t *ctx, const char *funding_status, *announce_status, *shutdown_status COMPILER_WANTS_INIT("gcc 8.3.0"); - if (funding_locked[LOCAL] && funding_locked[REMOTE]) - funding_status = "Funding transaction locked."; - else if (!funding_locked[LOCAL] && !funding_locked[REMOTE]) + if (channel_ready[LOCAL] && channel_ready[REMOTE]) + funding_status = "Channel ready for use."; + else if (!channel_ready[LOCAL] && !channel_ready[REMOTE]) funding_status = tal_fmt(ctx, "Funding needs %d more" - " confirmations for lockin.", + " confirmations to be ready.", depth_togo); - else if (funding_locked[LOCAL] && !funding_locked[REMOTE]) - funding_status = "We've confirmed funding, they haven't yet."; - else if (!funding_locked[LOCAL] && funding_locked[REMOTE]) - funding_status = "They've confirmed funding, we haven't yet."; + else if (channel_ready[LOCAL] && !channel_ready[REMOTE]) + funding_status = "We've confirmed channel ready, they haven't yet."; + else if (!channel_ready[LOCAL] && channel_ready[REMOTE]) + funding_status = "They've confirmed channel ready, we haven't yet."; if (have_sigs) { if (have_sigs[LOCAL] && have_sigs[REMOTE]) diff --git a/common/billboard.h b/common/billboard.h index c6d8ded8cd3b..38106e5fff54 100644 --- a/common/billboard.h +++ b/common/billboard.h @@ -5,7 +5,7 @@ #include char *billboard_message(const tal_t *ctx, - const bool funding_locked[NUM_SIDES], + const bool channel_ready[NUM_SIDES], const bool have_sigs[NUM_SIDES], const bool shutdown_sent[NUM_SIDES], u32 depth_togo, diff --git a/doc/PLUGINS.md b/doc/PLUGINS.md index 7751f348abf6..b7e6d17a4cc3 100644 --- a/doc/PLUGINS.md +++ b/doc/PLUGINS.md @@ -441,7 +441,7 @@ if the funding transaction has been included into a block. "id": "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f", "funding_msat": 100000000, "funding_txid": "4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b", - "funding_locked": false + "channel_ready": false } } ``` diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index a2f84ee61da0..2a552017c2d3 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -1790,7 +1790,7 @@ void dualopen_tell_depth(struct subd *dualopend, } else channel_set_billboard(channel, false, tal_fmt(tmpctx, "Funding needs %d more" - " confirmations for lockin.", + " confirmations to be ready.", to_go)); } diff --git a/lightningd/notification.c b/lightningd/notification.c index 82ad1f616aed..5c0c339817d2 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -201,13 +201,15 @@ static void channel_opened_notification_serialize(struct json_stream *stream, struct node_id *node_id, struct amount_sat *funding_sat, struct bitcoin_txid *funding_txid, - bool funding_locked) + bool channel_ready) { json_object_start(stream, "channel_opened"); json_add_node_id(stream, "id", node_id); json_add_amount_sats_deprecated(stream, "amount", "funding_msat", *funding_sat); json_add_txid(stream, "funding_txid", funding_txid); - json_add_bool(stream, "funding_locked", funding_locked); + if (deprecated_apis) + json_add_bool(stream, "funding_locked", channel_ready); + json_add_bool(stream, "channel_ready", channel_ready); json_object_end(stream); } @@ -216,7 +218,7 @@ REGISTER_NOTIFICATION(channel_opened, void notify_channel_opened(struct lightningd *ld, struct node_id *node_id, struct amount_sat *funding_sat, struct bitcoin_txid *funding_txid, - bool funding_locked) + bool channel_ready) { void (*serialize)(struct json_stream *, struct node_id *, @@ -226,7 +228,7 @@ void notify_channel_opened(struct lightningd *ld, struct node_id *node_id, struct jsonrpc_notification *n = jsonrpc_notification_start(NULL, channel_opened_notification_gen.topic); - serialize(n->stream, node_id, funding_sat, funding_txid, funding_locked); + serialize(n->stream, node_id, funding_sat, funding_txid, channel_ready); jsonrpc_notification_end(n); plugins_notify(ld->plugins, take(n)); } diff --git a/lightningd/notification.h b/lightningd/notification.h index 8eb00c0a3057..ab9bddd607b5 100644 --- a/lightningd/notification.h +++ b/lightningd/notification.h @@ -47,7 +47,7 @@ void notify_invoice_creation(struct lightningd *ld, struct amount_msat *amount, void notify_channel_opened(struct lightningd *ld, struct node_id *node_id, struct amount_sat *funding_sat, struct bitcoin_txid *funding_txid, - bool funding_locked); + bool channel_ready); void notify_channel_state_changed(struct lightningd *ld, struct node_id *peer_id, diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 0c40c0fdc6aa..03e47911c3d0 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -3620,7 +3620,7 @@ static void do_reconnect_dance(struct state *state) } if (state->channel_ready[LOCAL]) { - status_debug("Retransmitting funding_locked for channel %s", + status_debug("Retransmitting channel_ready for channel %s", type_to_string(tmpctx, struct channel_id, &state->channel_id)); diff --git a/openingd/dualopend_wire.csv b/openingd/dualopend_wire.csv index 7f49f37fe1ea..45defc1f4ead 100644 --- a/openingd/dualopend_wire.csv +++ b/openingd/dualopend_wire.csv @@ -50,8 +50,8 @@ msgdata,dualopend_reinit,their_basepoints,basepoints, msgdata,dualopend_reinit,remote_per_commit,pubkey, msgdata,dualopend_reinit,funding_psbt,wally_psbt, msgdata,dualopend_reinit,opener,enum side, -msgdata,dualopend_reinit,local_funding_locked,bool, -msgdata,dualopend_reinit,remote_funding_locked,bool, +msgdata,dualopend_reinit,local_channel_ready,bool, +msgdata,dualopend_reinit,remote_channel_ready,bool, msgdata,dualopend_reinit,send_shutdown,bool, msgdata,dualopend_reinit,remote_shutdown_received,bool, msgdata,dualopend_reinit,local_shutdown_len,u16, diff --git a/tests/test_closing.py b/tests/test_closing.py index f278d9c93a19..f635a17c4e84 100644 --- a/tests/test_closing.py +++ b/tests/test_closing.py @@ -33,9 +33,9 @@ def test_closing_simple(node_factory, bitcoind, chainparams): assert bitcoind.rpc.getmempoolinfo()['size'] == 0 billboard = only_one(l1.rpc.listpeers(l2.info['id'])['peers'][0]['channels'])['status'] - assert billboard == ['CHANNELD_NORMAL:Funding transaction locked.'] + assert billboard == ['CHANNELD_NORMAL:Channel ready for use.'] billboard = only_one(l2.rpc.listpeers(l1.info['id'])['peers'][0]['channels'])['status'] - assert billboard == ['CHANNELD_NORMAL:Funding transaction locked.'] + assert billboard == ['CHANNELD_NORMAL:Channel ready for use.'] bitcoind.generate_block(5) @@ -44,7 +44,7 @@ def test_closing_simple(node_factory, bitcoind, chainparams): billboard = only_one(l1.rpc.listpeers(l2.info['id'])['peers'][0]['channels'])['status'] # This may either be from a local_update or an announce, so just # check for the substring - assert 'CHANNELD_NORMAL:Funding transaction locked.' in billboard[0] + assert 'CHANNELD_NORMAL:Channel ready for use.' in billboard[0] l1.rpc.close(chan) diff --git a/tests/test_connection.py b/tests/test_connection.py index 3f915c8c6fb4..7040d4dcd08c 100644 --- a/tests/test_connection.py +++ b/tests/test_connection.py @@ -669,9 +669,9 @@ def test_reconnect_gossiping(node_factory): @pytest.mark.openchannel('v1') @pytest.mark.openchannel('v2') def test_reconnect_no_update(node_factory, executor, bitcoind): - """Test that funding_locked is retransmitted on reconnect if new channel + """Test that channel_ready is retransmitted on reconnect if new channel - This tests if the `funding_locked` is sent if we receive a + This tests if the `channel_ready` is sent if we receive a `channel_reestablish` message with `next_commitment_number` == 1 and our `next_commitment_number` == 1. @@ -689,14 +689,14 @@ def test_reconnect_no_update(node_factory, executor, bitcoind): l1.rpc.connect(l2.info["id"], "localhost", l2.port) # LightningNode.fundchannel will fund the channel and generate a - # block. The block triggers the funding_locked message, which + # block. The block triggers the channel_ready message, which # causes a disconnect. The retransmission is then caused by the # automatic retry. fundchannel_exec = executor.submit(l1.fundchannel, l2, 10**6, False) if l1.config('experimental-dual-fund'): - l1.daemon.wait_for_log(r"dualopend.* Retransmitting funding_locked for channel") + l1.daemon.wait_for_log(r"dualopend.* Retransmitting channel_ready for channel") else: - l1.daemon.wait_for_log(r"channeld.* Retransmitting funding_locked for channel") + l1.daemon.wait_for_log(r"channeld.* Retransmitting channel_ready for channel") sync_blockheight(bitcoind, [l1, l2]) fundchannel_exec.result() l1.stop() @@ -706,7 +706,7 @@ def test_reconnect_no_update(node_factory, executor, bitcoind): # Close will trigger the -WIRE_SHUTDOWN and we then wait for the # automatic reconnection to trigger the retransmission. l1.rpc.close(l2.info['id'], 0) - l2.daemon.wait_for_log(r"channeld.* Retransmitting funding_locked for channel") + l2.daemon.wait_for_log(r"channeld.* Retransmitting channel_ready for channel") l1.daemon.wait_for_log(r"CLOSINGD_COMPLETE") @@ -913,7 +913,7 @@ def no_blocks_above(req): # l2 will now uses (REMOTE's) announcement_signatures it has stored wait_for(lambda: only_one(l2.rpc.listpeers()['peers'][0]['channels'])['status'] == [ 'CHANNELD_NORMAL:Reconnected, and reestablished.', - 'CHANNELD_NORMAL:Funding transaction locked. Channel announced.']) + 'CHANNELD_NORMAL:Channel ready for use. Channel announced.']) # But l2 still sends its own sigs on reconnect l2.daemon.wait_for_logs([r'peer_out WIRE_ANNOUNCEMENT_SIGNATURES', diff --git a/tests/test_misc.py b/tests/test_misc.py index 9e656a0166a3..d505820be3f3 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -1108,7 +1108,7 @@ def test_funding_reorg_private(node_factory, bitcoind): daemon = 'DUALOPEND' if l1.config('experimental-dual-fund') else 'CHANNELD' wait_for(lambda: only_one(l1.rpc.listpeers()['peers'][0]['channels'])['status'] - == ['{}_AWAITING_LOCKIN:Funding needs 1 more confirmations for lockin.'.format(daemon)]) + == ['{}_AWAITING_LOCKIN:Funding needs 1 more confirmations to be ready.'.format(daemon)]) bitcoind.generate_block(1) # height 107 l1.wait_channel_active('106x1x0') l2.wait_channel_active('106x1x0') @@ -1166,7 +1166,7 @@ def no_more_blocks(req): wait_for(lambda: only_one(l2.rpc.listpeers()['peers'][0]['channels'])['status'] == [ 'CHANNELD_NORMAL:Reconnected, and reestablished.', - 'CHANNELD_NORMAL:Funding transaction locked. They need our announcement signatures.']) + 'CHANNELD_NORMAL:Channel ready for use. They need our announcement signatures.']) # Unblinding l2 brings it back in sync, restarts channeld and sends its announce sig l2.daemon.rpcproxy.mock_rpc('getblockhash', None) @@ -1176,7 +1176,7 @@ def no_more_blocks(req): wait_for(lambda: only_one(l2.rpc.listpeers()['peers'][0]['channels'])['status'] == [ 'CHANNELD_NORMAL:Reconnected, and reestablished.', - 'CHANNELD_NORMAL:Funding transaction locked. Channel announced.']) + 'CHANNELD_NORMAL:Channel ready for use. Channel announced.']) l1.rpc.close(l2.info['id']) bitcoind.generate_block(1, True) diff --git a/tests/test_opening.py b/tests/test_opening.py index 7072e82165d4..207ff508633d 100644 --- a/tests/test_opening.py +++ b/tests/test_opening.py @@ -1275,7 +1275,7 @@ def test_zeroconf_mindepth(bitcoind, node_factory): bitcoind.generate_block(2, wait_for_mempool=1) # Confirm on the l2 side. l2.daemon.wait_for_log(r'peer_out WIRE_CHANNEL_READY') - # l1 should not be sending funding_locked/channel_ready yet, it is + # l1 should not be sending channel_ready yet, it is # configured to wait for 6 confirmations. assert not l1.daemon.is_in_log(r'peer_out WIRE_CHANNEL_READY') From 7580973d98384292c40c83bf88c70530383bfa00 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:42:31 +0930 Subject: [PATCH 18/20] doc: upgrade to BOLTs 2ecc091f3484f7a3450e7f5543ae851edd1e0761 I disagree with this change, so I've commented and added a FIXME. Signed-off-by: Rusty Russell --- Makefile | 2 +- common/gossip_constants.h | 2 +- gossipd/gossipd.c | 2 +- gossipd/routing.c | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 3d11b3299ba0..6c8a99fef662 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ CCANDIR := ccan # Where we keep the BOLT RFCs BOLTDIR := ../bolts/ -DEFAULT_BOLTVERSION := bc86304b4b0af5fd5ce9d24f74e2ebbceb7e2730 +DEFAULT_BOLTVERSION := 2ecc091f3484f7a3450e7f5543ae851edd1e0761 # Can be overridden on cmdline. BOLTVERSION := $(DEFAULT_BOLTVERSION) diff --git a/common/gossip_constants.h b/common/gossip_constants.h index 3ce395eac70e..436db62a4ab6 100644 --- a/common/gossip_constants.h +++ b/common/gossip_constants.h @@ -62,7 +62,7 @@ /* BOLT #7: * * A node: - * - if a channel's oldest `channel_update`s `timestamp` is older than two weeks + * - if a channel's latest `channel_update`s `timestamp` is older than two weeks * (1209600 seconds): * - MAY prune the channel. * - MAY ignore the channel. diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 8c42eec96bc7..84a588775b46 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -606,7 +606,7 @@ static struct io_plan *connectd_req(struct io_conn *conn, /* BOLT #7: * * A node: - * - if a channel's oldest `channel_update`s `timestamp` is older than two weeks + * - if a channel's latest `channel_update`s `timestamp` is older than two weeks * (1209600 seconds): * - MAY prune the channel. * - MAY ignore the channel. diff --git a/gossipd/routing.c b/gossipd/routing.c index 6bdc0020d64f..253fffd06ea6 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -1926,10 +1926,12 @@ void route_prune(struct routing_state *rstate) continue; /* BOLT #7: - * - if a channel's oldest `channel_update`s `timestamp` is + * - if a channel's latest `channel_update`s `timestamp` is * older than two weeks (1209600 seconds): * - MAY prune the channel. */ + /* FIXME: I disagree with the above quote: it used to say "oldest", which is what we + use here: */ /* This is a fancy way of saying "both ends must refresh!" */ if (!is_halfchan_defined(&chan->half[0]) || chan->half[0].bcast.timestamp < highwater From 4d6efb4a824383475a63cf0a62f6e16cb57f31ba Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:43:31 +0930 Subject: [PATCH 19/20] doc: upgrade to BOLTs 341ec844f13c0c0abc4fe849059fbb98173f9766 This is a slightly looser behavior, so no change needed. Signed-off-by: Rusty Russell --- Makefile | 2 +- channeld/channeld.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 6c8a99fef662..2bbfe8894132 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ CCANDIR := ccan # Where we keep the BOLT RFCs BOLTDIR := ../bolts/ -DEFAULT_BOLTVERSION := 2ecc091f3484f7a3450e7f5543ae851edd1e0761 +DEFAULT_BOLTVERSION := 341ec844f13c0c0abc4fe849059fbb98173f9766 # Can be overridden on cmdline. BOLTVERSION := $(DEFAULT_BOLTVERSION) diff --git a/channeld/channeld.c b/channeld/channeld.c index 541f9460cd36..c4f2a744dbb9 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -1254,8 +1254,9 @@ static void send_commit(struct peer *peer) /* BOLT #2: * - * - if no HTLCs remain in either commitment transaction: - * - MUST NOT send any `update` message after a `shutdown`. + * - if no HTLCs remain in either commitment transaction (including dust HTLCs) + * and neither side has a pending `revoke_and_ack` to send: + * - MUST NOT send any `update` message after that point. */ if (peer->shutdown_sent[LOCAL] && !num_channel_htlcs(peer->channel)) { status_debug("Can't send commit: final shutdown phase"); From 380ee93833110cb72fd0c8b9599935a816d97063 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 10 Sep 2022 11:44:31 +0930 Subject: [PATCH 20/20] doc: include recent BOLT recommendation on grace period. This includes the recommendation that we use 10 minute grace period, so add quotes to where we use that. Signed-off-by: Rusty Russell --- lightningd/peer_control.c | 4 ++++ lightningd/peer_htlcs.c | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index d13b53ff7204..5e79ff6aaadd 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2585,6 +2585,10 @@ static struct command_result *json_setchannelfee(struct command *cmd, &base, cmd->ld->config.fee_base), p_opt_def("ppm", param_number, &ppm, cmd->ld->config.fee_per_satoshi), + /* BOLT #7: + * If it creates a new `channel_update` with updated channel parameters: + * - SHOULD keep accepting the previous channel parameters for 10 minutes + */ p_opt_def("enforcedelay", param_number, &delaysecs, 600), NULL)) return command_param_failed(); diff --git a/lightningd/peer_htlcs.c b/lightningd/peer_htlcs.c index 62a6993ad71f..1333d4be693a 100644 --- a/lightningd/peer_htlcs.c +++ b/lightningd/peer_htlcs.c @@ -720,7 +720,10 @@ static void forward_htlc(struct htlc_in *hin, if (!check_fwd_amount(hin, amt_to_forward, hin->msat, next->feerate_base, next->feerate_ppm)) { - /* Are we in old-fee grace-period? */ + /* BOLT #7: + * - If it creates a new `channel_update` with updated channel parameters: + * - SHOULD keep accepting the previous channel parameters for 10 minutes + */ if (!time_before(time_now(), next->old_feerate_timeout) || !check_fwd_amount(hin, amt_to_forward, hin->msat, next->old_feerate_base,