mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-14 19:44:26 +01:00
lightningd: implement receiving warnings.
This takes from the draft spec at https://github.com/lightningnetwork/lightning-rfc/pull/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.
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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,
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -69,11 +69,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);
|
||||
@@ -154,7 +159,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
|
||||
@@ -181,12 +186,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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
13
wire/extracted_peer_warning.patch
Normal file
13
wire/extracted_peer_warning.patch
Normal file
@@ -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,
|
||||
@@ -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:
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
|
Reference in New Issue
Block a user