From fc3e679c97781bb1421103de778b627982246ff7 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 13 Jan 2021 13:30:20 +1030 Subject: [PATCH] lightningd: control onion messages by `experimental-onion-messages` option. Note that this also changes so the feature is not represented in channels, reflecting the recent drafts. Signed-off-by: Rusty Russell Changelog-Added: `experimental-onion-messages` enables send, receive and relay of onion messages. --- common/features.c | 11 +++++------ common/features.h | 2 -- gossipd/gossipd.c | 14 +++++--------- lightningd/gossip_control.c | 6 ------ lightningd/onion_message.c | 7 +++++-- lightningd/options.c | 18 ++++++++++++++++++ tests/test_misc.py | 3 +-- tests/utils.py | 3 --- 8 files changed, 34 insertions(+), 30 deletions(-) diff --git a/common/features.c b/common/features.c index 6f080153c..9c1c73ea8 100644 --- a/common/features.c +++ b/common/features.c @@ -68,17 +68,16 @@ static const struct feature_style feature_styles[] = { .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, [CHANNEL_FEATURE] = FEATURE_DONT_REPRESENT } }, + { OPT_ONION_MESSAGES, + .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, + [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, + [BOLT11_FEATURE] = FEATURE_REPRESENT, + [CHANNEL_FEATURE] = FEATURE_DONT_REPRESENT} }, #if EXPERIMENTAL_FEATURES { OPT_ANCHOR_OUTPUTS, .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, [CHANNEL_FEATURE] = FEATURE_DONT_REPRESENT } }, - { OPT_ONION_MESSAGES, - .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, - [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, - [BOLT11_FEATURE] = FEATURE_REPRESENT, - [CHANNEL_FEATURE] = FEATURE_REPRESENT_AS_OPTIONAL} }, - { OPT_DUAL_FUND, .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, diff --git a/common/features.h b/common/features.h index e6d2463f3..e928a73c9 100644 --- a/common/features.h +++ b/common/features.h @@ -122,7 +122,5 @@ u8 *featurebits_or(const tal_t *ctx, const u8 *f1 TAKES, const u8 *f2 TAKES); * * | 102/103 | `option_onion_messages` |... INC+ ... */ -#if EXPERIMENTAL_FEATURES #define OPT_ONION_MESSAGES 102 -#endif #endif /* LIGHTNING_COMMON_FEATURES_H */ diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index 572bd152d..7e351efa8 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -435,7 +435,6 @@ static bool handle_local_channel_announcement(struct daemon *daemon, return true; } -#if EXPERIMENTAL_FEATURES /* Peer sends onion msg. */ static u8 *handle_onion_message(struct peer *peer, const u8 *msg) { @@ -450,6 +449,11 @@ static u8 *handle_onion_message(struct peer *peer, const u8 *msg) struct tlv_onionmsg_payload *om; struct tlv_onion_message_tlvs *tlvs = tlv_onion_message_tlvs_new(msg); + /* Ignore unless explicitly turned on. */ + if (!feature_offered(peer->daemon->our_features->bits[NODE_ANNOUNCE_FEATURE], + OPT_ONION_MESSAGES)) + return NULL; + /* FIXME: ratelimit! */ if (!fromwire_onion_message(msg, msg, &onion, tlvs)) return towire_errorfmt(peer, NULL, "Bad onion_message"); @@ -690,7 +694,6 @@ static struct io_plan *onionmsg_req(struct io_conn *conn, struct daemon *daemon, } return daemon_conn_read_next(conn, daemon->master); } -#endif /* EXPERIMENTAL_FEATURES */ /*~ This is where the per-peer daemons send us messages. It's either forwarded * gossip, or a request for information. We deliberately use non-overlapping @@ -731,11 +734,9 @@ static struct io_plan *peer_msg_in(struct io_conn *conn, case WIRE_PONG: err = handle_pong(peer, msg); goto handled_relay; -#if EXPERIMENTAL_FEATURES case WIRE_ONION_MESSAGE: err = handle_onion_message(peer, msg); goto handled_relay; -#endif /* These are non-gossip messages (!is_msg_for_gossipd()) */ case WIRE_INIT: @@ -757,9 +758,6 @@ static struct io_plan *peer_msg_in(struct io_conn *conn, case WIRE_CHANNEL_REESTABLISH: case WIRE_ANNOUNCEMENT_SIGNATURES: case WIRE_GOSSIP_TIMESTAMP_FILTER: -#if !EXPERIMENTAL_FEATURES - case WIRE_ONION_MESSAGE: -#endif #if EXPERIMENTAL_FEATURES case WIRE_TX_ADD_INPUT: case WIRE_TX_REMOVE_INPUT: @@ -1934,9 +1932,7 @@ static struct io_plan *recv_req(struct io_conn *conn, #endif /* !DEVELOPER */ case WIRE_GOSSIPD_SEND_ONIONMSG: -#if EXPERIMENTAL_FEATURES return onionmsg_req(conn, daemon, msg); -#endif /* We send these, we don't receive them */ case WIRE_GOSSIPD_GETNODES_REPLY: case WIRE_GOSSIPD_GETROUTE_REPLY: diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index f493d5acc..6843c0980 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -161,18 +161,12 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY: break; -#if EXPERIMENTAL_FEATURES case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US: handle_onionmsg_to_us(gossip->ld, msg); break; case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD: handle_onionmsg_forward(gossip->ld, msg); break; -#else - case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US: - case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD: - break; -#endif case WIRE_GOSSIPD_PING_REPLY: ping_reply(gossip, msg); break; diff --git a/lightningd/onion_message.c b/lightningd/onion_message.c index 4fe9003ce..7b668b77c 100644 --- a/lightningd/onion_message.c +++ b/lightningd/onion_message.c @@ -6,7 +6,6 @@ #include #include -#if EXPERIMENTAL_FEATURES struct onion_message_hook_payload { /* Optional */ struct pubkey *blinding_in; @@ -406,6 +405,11 @@ static struct command_result *json_send_onion_message(struct command *cmd, NULL)) return command_param_failed(); + if (!feature_offered(cmd->ld->our_features->bits[NODE_ANNOUNCE_FEATURE], + OPT_ONION_MESSAGES)) + return command_fail(cmd, LIGHTNINGD, + "experimental-onion-messages not enabled"); + node_id_from_pubkey(&first_id, &hops[0].id); /* Sanity check first; gossipd doesn't bother telling us if peer @@ -461,4 +465,3 @@ static const struct json_command send_onion_message_command = { "Send message over {hops} (id, [short_channel_id], [blinding], [enctlv], [invoice], [invoice_request], [invoice_error], [rawtlv]) with optional {reply_path} (blinding, path[id, enctlv])" }; AUTODATA(json_command, &send_onion_message_command); -#endif /* EXPERIMENTAL_FEATURES */ diff --git a/lightningd/options.c b/lightningd/options.c index c37213010..5d77e5958 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -799,6 +799,14 @@ static char *opt_set_dual_fund(struct lightningd *ld) return NULL; } +static char *opt_set_onion_messages(struct lightningd *ld) +{ + feature_set_or(ld->our_features, + take(feature_set_for_feature(NULL, + OPTIONAL_FEATURE(OPT_ONION_MESSAGES)))); + return NULL; +} + static void register_opts(struct lightningd *ld) { /* This happens before plugins started */ @@ -846,6 +854,11 @@ static void register_opts(struct lightningd *ld) " and allow peers to establish channels" " via v2 channel open protocol"); + /* This affects our features, so set early. */ + opt_register_early_noarg("--experimental-onion-messages", + opt_set_onion_messages, ld, + "EXPERIMENTAL: enable send, receive and relay" + " of onion messages"); opt_register_noarg("--help|-h", opt_lightningd_usage, ld, "Print this message."); @@ -1262,6 +1275,11 @@ static void add_config(struct lightningd *ld, feature_offered(ld->our_features ->bits[INIT_FEATURE], OPT_DUAL_FUND)); + } else if (opt->cb == (void *)opt_set_onion_messages) { + json_add_bool(response, name0, + feature_offered(ld->our_features + ->bits[INIT_FEATURE], + OPT_ONION_MESSAGES)); } else if (opt->cb == (void *)plugin_opt_flag_set) { /* Noop, they will get added below along with the * OPT_HASARG options. */ diff --git a/tests/test_misc.py b/tests/test_misc.py index 1004f2f2f..f48c165df 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -2297,9 +2297,8 @@ def test_sendcustommsg(node_factory): serialized=serialized, peer_id=l2.info['id'])) -@unittest.skipIf(not EXPERIMENTAL_FEATURES, "Needs sendonionmessage") def test_sendonionmessage(node_factory): - l1, l2, l3 = node_factory.line_graph(3) + l1, l2, l3 = node_factory.line_graph(3, opts={'experimental-onion-messages': None}) blindedpathtool = os.path.join(os.path.dirname(__file__), "..", "devtools", "blindedpath") diff --git a/tests/utils.py b/tests/utils.py index 37fc9444c..e91a92715 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -49,9 +49,6 @@ def expected_node_features(wumbo_channels=False, extra=[]): def expected_channel_features(wumbo_channels=False, extra=[]): """Return the expected channel features hexstring for this configuration""" features = [] - if EXPERIMENTAL_FEATURES: - # OPT_ONION_MESSAGES - features += [103] return hex_bits(features + extra)