Skip to content

Commit

Permalink
Add option to allow even custom messages to be sent
Browse files Browse the repository at this point in the history
Changelog-Experimental: config: new option --experimental-all-onion-messages, which behaves like --experimental-onion-messages but also allow even-numbered messages to be sent
  • Loading branch information
benthecarman committed May 30, 2022
1 parent 74ddc15 commit a5b9fb6
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 4 deletions.
1 change: 1 addition & 0 deletions connectd/multiplex.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ static bool handle_custommsg(struct daemon *daemon,
const u8 *msg)
{
enum peer_wire type = fromwire_peektype(msg);
// fixme use allow_even_custom_message config here
if (type % 2 == 1 && !peer_wire_is_defined(type)) {
/* The message is not part of the messages we know how to
* handle. Assuming this is a custommsg, we just forward it to the
Expand Down
2 changes: 2 additions & 0 deletions doc/lightning-listconfigs.7

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions doc/lightning-listconfigs.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ On success, an object is returned, containing:
- **large-channels** (boolean, optional): `large-channels` field from config or cmdline, or default
- **experimental-dual-fund** (boolean, optional): `experimental-dual-fund` field from config or cmdline, or default
- **experimental-onion-messages** (boolean, optional): `experimental-onion-messages` field from config or cmdline, or default
- **experimental-all-onion-messages** (boolean, optional): `experimental-all-onion-messages` field from config or cmdline, or default
- **experimental-offers** (boolean, optional): `experimental-offers` field from config or cmdline, or default
- **experimental-shutdown-wrong-funding** (boolean, optional): `experimental-shutdown-wrong-funding` field from config or cmdline, or default
- **experimental-websocket-port** (u16, optional): `experimental-websocket-port` field from config or cmdline, or default
Expand Down
5 changes: 3 additions & 2 deletions doc/lightning-sendcustommsg.7.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ top, not for direct use by end-users.

The message must be a hex encoded well-formed message, including the 2-byte
type prefix, but excluding the length prefix which will be added by the RPC
method. The messages must not use even-numbered types, since these may require
synchronous handling on the receiving side, and can cause the connection to be
method. The messages must not use even-numbered types, unless using
`--experimental-all-onion-messages`, since these may require synchronous
handling on the receiving side, and can cause the connection to be
dropped. The message types may also not use one of the internally handled
types, since that may cause issues with the internal state tracking of
Core Lightning.
Expand Down
5 changes: 5 additions & 0 deletions doc/lightningd-config.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,11 @@ be listed with `lightningd --list-features-only`.
Specifying this enables sending, forwarding and receiving onion messages,
which are in draft status in the BOLT specifications.

**experimental-all-onion-messages**

Specifying this enables the same as **experimental-onion-messages**,
but also allows even numbered messages to be sent.

**experimental-offers**

Specifying this enables the `offers` and `fetchinvoice` plugins and
Expand Down
4 changes: 4 additions & 0 deletions doc/schemas/listconfigs.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@
"type": "boolean",
"description": "`experimental-onion-messages` field from config or cmdline, or default"
},
"experimental-all-onion-messages": {
"type": "boolean",
"description": "`experimental-all-onion-messages` field from config or cmdline, or default"
},
"experimental-offers": {
"type": "boolean",
"description": "`experimental-offers` field from config or cmdline, or default"
Expand Down
6 changes: 4 additions & 2 deletions lightningd/connect_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,13 +656,15 @@ static struct command_result *json_sendcustommsg(struct command *cmd,
type, peer_wire_name(type));
}

if (type % 2 == 0) {
if (type % 2 == 0 && !cmd->ld->config.allow_even_custom_message) {
return command_fail(
cmd, JSONRPC2_INVALID_REQUEST,
"Cannot send even-typed %d custom message. Currently "
"custom messages are limited to odd-numbered message "
"types, as even-numbered types might result in "
"disconnections.",
"disconnections. If you really want to send even custom "
"messages, add the --experimental-all-onion-messages "
"to the lightningd configuration",
type);
}

Expand Down
3 changes: 3 additions & 0 deletions lightningd/lightningd.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ struct config {

/* EXPERIMENTAL: offers support */
bool exp_offers;

/* Do we allow even custom messages to be sent */
bool allow_even_custom_messages;
};

typedef STRMAP(const char *) alt_subdaemon_map;
Expand Down
16 changes: 16 additions & 0 deletions lightningd/options.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,8 @@ static const struct config testnet_config = {
.connection_timeout_secs = 60,

.exp_offers = IFEXPERIMENTAL(true, false),

.allow_even_custom_messages = false,
};

/* aka. "Dude, where's my coins?" */
Expand Down Expand Up @@ -861,6 +863,8 @@ static const struct config mainnet_config = {
.connection_timeout_secs = 60,

.exp_offers = IFEXPERIMENTAL(true, false),

.allow_even_custom_messages = false,
};

static void check_config(struct lightningd *ld)
Expand Down Expand Up @@ -997,6 +1001,12 @@ static char *opt_set_onion_messages(struct lightningd *ld)
return NULL;
}

static char *opt_set_all_onion_messages(struct lightningd *ld)
{
ld->config.allow_even_custom_messages = true;
return opt_set_onion_messages(ld);
}

static char *opt_set_shutdown_wrong_funding(struct lightningd *ld)
{
feature_set_or(ld->our_features,
Expand Down Expand Up @@ -1063,6 +1073,10 @@ static void register_opts(struct lightningd *ld)
opt_set_onion_messages, ld,
"EXPERIMENTAL: enable send, receive and relay"
" of onion messages");
opt_register_early_noarg("--experimental-all-onion-messages",
opt_set_all_onion_messages, ld,
"EXPERIMENTAL: enable send, receive and relay"
" of all onion messages");
opt_register_early_noarg("--experimental-offers",
opt_set_offers, ld,
"EXPERIMENTAL: enable send and receive of offers"
Expand Down Expand Up @@ -1519,6 +1533,8 @@ static void add_config(struct lightningd *ld,
feature_offered(ld->our_features
->bits[INIT_FEATURE],
OPT_ONION_MESSAGES));
} else if (opt->cb == (void *)opt_set_all_onion_messages) {
json_add_bool(response, name0, ld->config.allow_even_custom_messages);
} else if (opt->cb == (void *)opt_set_offers) {
json_add_bool(response, name0, ld->config.exp_offers);
} else if (opt->cb == (void *)opt_set_shutdown_wrong_funding) {
Expand Down
53 changes: 53 additions & 0 deletions tests/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -2209,6 +2209,59 @@ def test_sendcustommsg(node_factory):
])


def test_even_sendcustommsg(node_factory):
"""Check that we can send even custommsgs to peers in various states.
`l2` is the node under test. `l1` has a channel with `l2` and should
therefore be attached to `channeld`. `l4` is just connected, so it should
be attached to `openingd`. `l3` has a channel open, but is disconnected
and we can't send to it.
"""
opts = {'log-level': 'io', 'experimental-all-onion-messages': None,
'experimental-accept-extra-tlv-types': '43690', 'plugin': [
os.path.join(os.path.dirname(__file__), "plugins", "custommsg_b.py"),
os.path.join(os.path.dirname(__file__), "plugins", "custommsg_a.py")
]}
l1, l2, l3, l4 = node_factory.get_nodes(4, opts=opts)
node_factory.join_nodes([l1, l2, l3])
l2.connect(l4)
l3.stop()

# Even-numbered message
msg = hex(43690)[2:] + ('ff' * 30) + 'bb'

# This should work since the peer is currently owned by `channeld`
l2.rpc.sendcustommsg(l1.info['id'], msg)
l2.daemon.wait_for_log(
r'{peer_id}-{owner}-chan#[0-9]: \[OUT\] {msg}'.format(
owner='channeld', msg=msg, peer_id=l1.info['id']
)
)
l1.daemon.wait_for_log(r'\[IN\] {}'.format(msg))
l1.daemon.wait_for_logs([
r'Got custommessage_a {msg} from peer {peer_id}'.format(
msg=msg, peer_id=l2.info['id']),
r'Got custommessage_b {msg} from peer {peer_id}'.format(
msg=msg, peer_id=l2.info['id'])
])

# This should work since the peer is currently owned by `openingd`
l2.rpc.sendcustommsg(l4.info['id'], msg)
l2.daemon.wait_for_log(
r'{peer_id}-{owner}-chan#[0-9]: \[OUT\] {msg}'.format(
owner='openingd', msg=msg, peer_id=l4.info['id']
)
)
l4.daemon.wait_for_log(r'\[IN\] {}'.format(msg))
l4.daemon.wait_for_logs([
r'Got custommessage_a {msg} from peer {peer_id}'.format(
msg=msg, peer_id=l2.info['id']),
r'Got custommessage_b {msg} from peer {peer_id}'.format(
msg=msg, peer_id=l2.info['id']),
])


@pytest.mark.developer("needs --dev-force-privkey")
def test_getsharedsecret(node_factory):
"""
Expand Down

0 comments on commit a5b9fb6

Please sign in to comment.