Browse Source

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 <rusty@rustcorp.com.au>
Changelog-Added: `experimental-onion-messages` enables send, receive and relay of onion messages.
ppa
Rusty Russell 4 years ago
committed by Christian Decker
parent
commit
fc3e679c97
  1. 11
      common/features.c
  2. 2
      common/features.h
  3. 14
      gossipd/gossipd.c
  4. 6
      lightningd/gossip_control.c
  5. 7
      lightningd/onion_message.c
  6. 18
      lightningd/options.c
  7. 3
      tests/test_misc.py
  8. 3
      tests/utils.py

11
common/features.c

@ -68,17 +68,16 @@ static const struct feature_style feature_styles[] = {
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT,
[CHANNEL_FEATURE] = FEATURE_DONT_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 #if EXPERIMENTAL_FEATURES
{ OPT_ANCHOR_OUTPUTS, { OPT_ANCHOR_OUTPUTS,
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT,
[CHANNEL_FEATURE] = FEATURE_DONT_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, { OPT_DUAL_FUND,
.copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT, .copy_style = { [INIT_FEATURE] = FEATURE_REPRESENT,
[NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT, [NODE_ANNOUNCE_FEATURE] = FEATURE_REPRESENT,

2
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+ ... * | 102/103 | `option_onion_messages` |... INC+ ...
*/ */
#if EXPERIMENTAL_FEATURES
#define OPT_ONION_MESSAGES 102 #define OPT_ONION_MESSAGES 102
#endif
#endif /* LIGHTNING_COMMON_FEATURES_H */ #endif /* LIGHTNING_COMMON_FEATURES_H */

14
gossipd/gossipd.c

@ -435,7 +435,6 @@ static bool handle_local_channel_announcement(struct daemon *daemon,
return true; return true;
} }
#if EXPERIMENTAL_FEATURES
/* Peer sends onion msg. */ /* Peer sends onion msg. */
static u8 *handle_onion_message(struct peer *peer, const u8 *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_onionmsg_payload *om;
struct tlv_onion_message_tlvs *tlvs = tlv_onion_message_tlvs_new(msg); 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! */ /* FIXME: ratelimit! */
if (!fromwire_onion_message(msg, msg, &onion, tlvs)) if (!fromwire_onion_message(msg, msg, &onion, tlvs))
return towire_errorfmt(peer, NULL, "Bad onion_message"); 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); 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 /*~ 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 * 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: case WIRE_PONG:
err = handle_pong(peer, msg); err = handle_pong(peer, msg);
goto handled_relay; goto handled_relay;
#if EXPERIMENTAL_FEATURES
case WIRE_ONION_MESSAGE: case WIRE_ONION_MESSAGE:
err = handle_onion_message(peer, msg); err = handle_onion_message(peer, msg);
goto handled_relay; goto handled_relay;
#endif
/* These are non-gossip messages (!is_msg_for_gossipd()) */ /* These are non-gossip messages (!is_msg_for_gossipd()) */
case WIRE_INIT: case WIRE_INIT:
@ -757,9 +758,6 @@ static struct io_plan *peer_msg_in(struct io_conn *conn,
case WIRE_CHANNEL_REESTABLISH: case WIRE_CHANNEL_REESTABLISH:
case WIRE_ANNOUNCEMENT_SIGNATURES: case WIRE_ANNOUNCEMENT_SIGNATURES:
case WIRE_GOSSIP_TIMESTAMP_FILTER: case WIRE_GOSSIP_TIMESTAMP_FILTER:
#if !EXPERIMENTAL_FEATURES
case WIRE_ONION_MESSAGE:
#endif
#if EXPERIMENTAL_FEATURES #if EXPERIMENTAL_FEATURES
case WIRE_TX_ADD_INPUT: case WIRE_TX_ADD_INPUT:
case WIRE_TX_REMOVE_INPUT: case WIRE_TX_REMOVE_INPUT:
@ -1934,9 +1932,7 @@ static struct io_plan *recv_req(struct io_conn *conn,
#endif /* !DEVELOPER */ #endif /* !DEVELOPER */
case WIRE_GOSSIPD_SEND_ONIONMSG: case WIRE_GOSSIPD_SEND_ONIONMSG:
#if EXPERIMENTAL_FEATURES
return onionmsg_req(conn, daemon, msg); return onionmsg_req(conn, daemon, msg);
#endif
/* We send these, we don't receive them */ /* We send these, we don't receive them */
case WIRE_GOSSIPD_GETNODES_REPLY: case WIRE_GOSSIPD_GETNODES_REPLY:
case WIRE_GOSSIPD_GETROUTE_REPLY: case WIRE_GOSSIPD_GETROUTE_REPLY:

6
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: case WIRE_GOSSIPD_GET_STRIPPED_CUPDATE_REPLY:
break; break;
#if EXPERIMENTAL_FEATURES
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US: case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US:
handle_onionmsg_to_us(gossip->ld, msg); handle_onionmsg_to_us(gossip->ld, msg);
break; break;
case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD: case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD:
handle_onionmsg_forward(gossip->ld, msg); handle_onionmsg_forward(gossip->ld, msg);
break; break;
#else
case WIRE_GOSSIPD_GOT_ONIONMSG_TO_US:
case WIRE_GOSSIPD_GOT_ONIONMSG_FORWARD:
break;
#endif
case WIRE_GOSSIPD_PING_REPLY: case WIRE_GOSSIPD_PING_REPLY:
ping_reply(gossip, msg); ping_reply(gossip, msg);
break; break;

7
lightningd/onion_message.c

@ -6,7 +6,6 @@
#include <lightningd/plugin_hook.h> #include <lightningd/plugin_hook.h>
#include <lightningd/subd.h> #include <lightningd/subd.h>
#if EXPERIMENTAL_FEATURES
struct onion_message_hook_payload { struct onion_message_hook_payload {
/* Optional */ /* Optional */
struct pubkey *blinding_in; struct pubkey *blinding_in;
@ -406,6 +405,11 @@ static struct command_result *json_send_onion_message(struct command *cmd,
NULL)) NULL))
return command_param_failed(); 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); node_id_from_pubkey(&first_id, &hops[0].id);
/* Sanity check first; gossipd doesn't bother telling us if peer /* 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])" "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); AUTODATA(json_command, &send_onion_message_command);
#endif /* EXPERIMENTAL_FEATURES */

18
lightningd/options.c

@ -799,6 +799,14 @@ static char *opt_set_dual_fund(struct lightningd *ld)
return NULL; 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) static void register_opts(struct lightningd *ld)
{ {
/* This happens before plugins started */ /* This happens before plugins started */
@ -846,6 +854,11 @@ static void register_opts(struct lightningd *ld)
" and allow peers to establish channels" " and allow peers to establish channels"
" via v2 channel open protocol"); " 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, opt_register_noarg("--help|-h", opt_lightningd_usage, ld,
"Print this message."); "Print this message.");
@ -1262,6 +1275,11 @@ static void add_config(struct lightningd *ld,
feature_offered(ld->our_features feature_offered(ld->our_features
->bits[INIT_FEATURE], ->bits[INIT_FEATURE],
OPT_DUAL_FUND)); 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) { } else if (opt->cb == (void *)plugin_opt_flag_set) {
/* Noop, they will get added below along with the /* Noop, they will get added below along with the
* OPT_HASARG options. */ * OPT_HASARG options. */

3
tests/test_misc.py

@ -2297,9 +2297,8 @@ def test_sendcustommsg(node_factory):
serialized=serialized, peer_id=l2.info['id'])) serialized=serialized, peer_id=l2.info['id']))
@unittest.skipIf(not EXPERIMENTAL_FEATURES, "Needs sendonionmessage")
def test_sendonionmessage(node_factory): 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") blindedpathtool = os.path.join(os.path.dirname(__file__), "..", "devtools", "blindedpath")

3
tests/utils.py

@ -49,9 +49,6 @@ def expected_node_features(wumbo_channels=False, extra=[]):
def expected_channel_features(wumbo_channels=False, extra=[]): def expected_channel_features(wumbo_channels=False, extra=[]):
"""Return the expected channel features hexstring for this configuration""" """Return the expected channel features hexstring for this configuration"""
features = [] features = []
if EXPERIMENTAL_FEATURES:
# OPT_ONION_MESSAGES
features += [103]
return hex_bits(features + extra) return hex_bits(features + extra)

Loading…
Cancel
Save