Skip to content

Commit

Permalink
lightningd: implement receiving warnings.
Browse files Browse the repository at this point in the history
This takes from the draft spec at lightning/bolts#834

Note that if this draft does not get included, the peer will simply
ignore the warning message (we always close the connection afterwards
anyway).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Added: Protocol: we now report the new (draft) warning message.
  • Loading branch information
rustyrussell committed Feb 2, 2021
1 parent 82f22b2 commit 5d011d3
Show file tree
Hide file tree
Showing 12 changed files with 55 additions and 20 deletions.
1 change: 1 addition & 0 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,7 @@ static void peer_in(struct peer *peer, const u8 *msg)
case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
case WIRE_PING:
case WIRE_PONG:
case WIRE_WARNING:
case WIRE_ERROR:
case WIRE_ONION_MESSAGE:
abort();
Expand Down
4 changes: 2 additions & 2 deletions common/peer_failed.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void peer_failed(struct per_peer_state *pps,
peer_fatal_continue(take(msg), pps);
}

/* We're failing because peer sent us an error message */
/* We're failing because peer sent us an error/warning message */
void peer_failed_received_errmsg(struct per_peer_state *pps,
const char *desc,
const struct channel_id *channel_id,
Expand All @@ -62,7 +62,7 @@ void peer_failed_received_errmsg(struct per_peer_state *pps,
channel_id = &all_channels;
msg = towire_status_peer_error(NULL, channel_id, desc, soft_error, pps,
NULL);
peer_billboard(true, "Received error from peer: %s", desc);
peer_billboard(true, "Received %s", desc);
peer_fatal_continue(take(msg), pps);
}

Expand Down
16 changes: 11 additions & 5 deletions common/read_peer_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,16 @@ u8 *peer_or_gossip_sync_read(const tal_t *ctx,

bool is_peer_error(const tal_t *ctx, const u8 *msg,
const struct channel_id *channel_id,
char **desc, bool *all_channels)
char **desc, bool *all_channels,
bool *warning)
{
struct channel_id err_chanid;

if (fromwire_peektype(msg) != WIRE_ERROR)
if (fromwire_peektype(msg) == WIRE_ERROR)
*warning = false;
else if (fromwire_peektype(msg) == WIRE_WARNING)
*warning = true;
else
return false;

*desc = sanitize_error(ctx, msg, &err_chanid);
Expand Down Expand Up @@ -153,7 +158,7 @@ bool handle_peer_gossip_or_error(struct per_peer_state *pps,
const u8 *msg TAKES)
{
char *err;
bool all_channels;
bool all_channels, warning;
struct channel_id actual;

#if DEVELOPER
Expand All @@ -180,12 +185,13 @@ bool handle_peer_gossip_or_error(struct per_peer_state *pps,
return true;
}

if (is_peer_error(tmpctx, msg, channel_id, &err, &all_channels)) {
if (is_peer_error(tmpctx, msg, channel_id, &err, &all_channels,
&warning)) {
if (err)
peer_failed_received_errmsg(pps, err,
all_channels
? NULL : channel_id,
soft_error);
warning || soft_error);

/* Ignore unknown channel errors. */
goto handled;
Expand Down
3 changes: 2 additions & 1 deletion common/read_peer_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ u8 *peer_or_gossip_sync_read(const tal_t *ctx,
* @channel_id: the channel id of the current channel.
* @desc: set to non-NULL if this describes a channel we care about.
* @all_channels: set to true if this applies to all channels.
* @warning: set to true if this is a warning, not an error.
*
* If @desc is NULL, ignore this message. Otherwise, that's usually passed
* to peer_failed_received_errmsg().
*/
bool is_peer_error(const tal_t *ctx, const u8 *msg,
const struct channel_id *channel_id,
char **desc, bool *all_channels);
char **desc, bool *all_channels, bool *warning);

/**
* is_wrong_channel - if it's a message about a different channel, return true
Expand Down
16 changes: 11 additions & 5 deletions common/wire_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,16 @@ char *sanitize_error(const tal_t *ctx, const u8 *errmsg,
struct channel_id dummy;
u8 *data;
size_t i;
bool warning;

if (!channel_id)
channel_id = &dummy;

if (!fromwire_error(ctx, errmsg, channel_id, &data))
if (fromwire_error(ctx, errmsg, channel_id, &data))
warning = false;
else if (fromwire_warning(ctx, errmsg, channel_id, &data))
warning = true;
else
return tal_fmt(ctx, "Invalid ERROR message '%s'",
tal_hex(ctx, errmsg));

Expand All @@ -79,9 +84,10 @@ char *sanitize_error(const tal_t *ctx, const u8 *errmsg,
}
}

return tal_fmt(ctx, "channel %s: %.*s",
channel_id_is_all(channel_id)
? "ALL"
: type_to_string(ctx, struct channel_id, channel_id),
return tal_fmt(ctx, "%s%s%s: %.*s",
warning ? "warning" : "error",
channel_id_is_all(channel_id) ? "": " channel ",
channel_id_is_all(channel_id) ? ""
: type_to_string(tmpctx, struct channel_id, channel_id),
(int)tal_count(data), (char *)data);
}
4 changes: 2 additions & 2 deletions common/wire_error.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ u8 *towire_errorfmtv(const tal_t *ctx,
bool channel_id_is_all(const struct channel_id *channel_id);

/**
* sanitize_error - extract and sanitize contents of WIRE_ERROR.
* sanitize_error - extract and sanitize contents of WIRE_ERROR/WIRE_WARNING.
*
* @ctx: context to allocate from
* @errmsg: the wire_error
* @errmsg: the wire_error or wire_warning
* @channel: (out) channel it's referring to, or NULL if don't care.
*/
char *sanitize_error(const tal_t *ctx, const u8 *errmsg,
Expand Down
1 change: 1 addition & 0 deletions gossipd/gossipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -737,6 +737,7 @@ static struct io_plan *peer_msg_in(struct io_conn *conn,
goto handled_relay;

/* These are non-gossip messages (!is_msg_for_gossipd()) */
case WIRE_WARNING:
case WIRE_INIT:
case WIRE_ERROR:
case WIRE_OPEN_CHANNEL:
Expand Down
5 changes: 3 additions & 2 deletions openingd/dualopend.c
Original file line number Diff line number Diff line change
Expand Up @@ -972,7 +972,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)
u8 *msg;
bool from_gossipd;
char *err;
bool all_channels;
bool all_channels, warning;
struct channel_id actual;

/* The event loop is responsible for freeing tmpctx, so our
Expand Down Expand Up @@ -1011,7 +1011,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)

/* A helper which decodes an error. */
if (is_peer_error(tmpctx, msg, &state->channel_id,
&err, &all_channels)) {
&err, &all_channels, &warning)) {
/* BOLT #1:
*
* - if no existing channel is referred to by the
Expand Down Expand Up @@ -1355,6 +1355,7 @@ static bool run_tx_interactive(struct state *state,
break;
case WIRE_INIT:
case WIRE_ERROR:
case WIRE_WARNING:
case WIRE_OPEN_CHANNEL:
case WIRE_ACCEPT_CHANNEL:
case WIRE_FUNDING_CREATED:
Expand Down
6 changes: 3 additions & 3 deletions openingd/openingd.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state,
u8 *msg;
bool from_gossipd;
char *err;
bool all_channels;
bool all_channels, warning;
struct channel_id actual;

/* The event loop is responsible for freeing tmpctx, so our
Expand Down Expand Up @@ -238,7 +238,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state,

/* A helper which decodes an error. */
if (is_peer_error(tmpctx, msg, &state->channel_id,
&err, &all_channels)) {
&err, &all_channels, &warning)) {
/* BOLT #1:
*
* - if no existing channel is referred to by the
Expand All @@ -262,7 +262,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state,
NULL, false);
}
negotiation_aborted(state, am_opener,
tal_fmt(tmpctx, "They sent error %s",
tal_fmt(tmpctx, "They sent %s",
err));
/* Return NULL so caller knows to stop negotiating. */
return NULL;
Expand Down
13 changes: 13 additions & 0 deletions wire/extracted_peer_warning.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
--- wire/peer_exp_wire.csv 2021-01-14 11:00:27.526336550 +1030
+++ - 2021-01-21 15:31:37.071118999 +1030
@@ -10,6 +10,10 @@
msgdata,error,channel_id,channel_id,
msgdata,error,len,u16,
msgdata,error,data,byte,len
+msgtype,warning,1
+msgdata,warning,channel_id,channel_id,
+msgdata,warning,len,u16,
+msgdata,warning,data,byte,len
msgtype,ping,18
msgdata,ping,num_pong_bytes,u16,
msgdata,ping,byteslen,u16,
2 changes: 2 additions & 0 deletions wire/peer_wire.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
static bool unknown_type(enum peer_wire t)
{
switch (t) {
case WIRE_WARNING:
case WIRE_INIT:
case WIRE_ERROR:
case WIRE_OPEN_CHANNEL:
Expand Down Expand Up @@ -64,6 +65,7 @@ bool is_msg_for_gossipd(const u8 *cursor)
case WIRE_PONG:
case WIRE_ONION_MESSAGE:
return true;
case WIRE_WARNING:
case WIRE_INIT:
case WIRE_ERROR:
case WIRE_OPEN_CHANNEL:
Expand Down
4 changes: 4 additions & 0 deletions wire/peer_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ msgtype,error,17
msgdata,error,channel_id,channel_id,
msgdata,error,len,u16,
msgdata,error,data,byte,len
msgtype,warning,1
msgdata,warning,channel_id,channel_id,
msgdata,warning,len,u16,
msgdata,warning,data,byte,len
msgtype,ping,18
msgdata,ping,num_pong_bytes,u16,
msgdata,ping,byteslen,u16,
Expand Down

0 comments on commit 5d011d3

Please sign in to comment.