common: add peer_error flag to treat this error as "soft".

The spec says to close the channel if they send us an error, but we
need to be more lenient to preserve channels with other
implementations.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2019-07-26 11:41:19 +09:30
parent f7a890ca35
commit dd79813a75
10 changed files with 27 additions and 8 deletions

View file

@ -42,7 +42,7 @@ void peer_failed(struct per_peer_state *pps,
/* Tell master the error so it can re-xmit. */
msg = towire_status_peer_error(NULL, channel_id,
desc, pps,
desc, false, pps,
err);
peer_billboard(true, desc);
tal_free(desc);
@ -59,7 +59,7 @@ void peer_failed_received_errmsg(struct per_peer_state *pps,
if (!channel_id)
channel_id = &all_channels;
msg = towire_status_peer_error(NULL, channel_id, desc, pps, NULL);
msg = towire_status_peer_error(NULL, channel_id, desc, false, pps, NULL);
peer_billboard(true, "Received error from peer: %s", desc);
peer_fatal_continue(take(msg), pps);
}

View file

@ -5,6 +5,8 @@ msgtype,status_peer_error,0xFFF4
# This is implied if error_for_them, but master tries not to parse packets.
msgdata,status_peer_error,channel,channel_id,
msgdata,status_peer_error,desc,wirestring,
# Take a deep breath, then try reconnecting to the precious little snowflake.
msgdata,status_peer_error,soft_error,bool,
msgdata,status_peer_error,pps,per_peer_state,
msgdata,status_peer_error,len,u16,
msgdata,status_peer_error,error_for_them,u8,len

1 #include <common/per_peer_state.h>
5 msgdata,status_peer_error,channel,channel_id,
6 msgdata,status_peer_error,desc,wirestring,
7 msgdata,status_peer_error,pps,per_peer_state, # Take a deep breath, then try reconnecting to the precious little snowflake.
8 msgdata,status_peer_error,soft_error,bool,
9 msgdata,status_peer_error,pps,per_peer_state,
10 msgdata,status_peer_error,len,u16,
11 msgdata,status_peer_error,error_for_them,u8,len
12

View file

@ -61,7 +61,6 @@ static void json_add_invoice(struct json_stream *response,
"amount_received_msat");
json_add_u64(response, "paid_at", inv->paid_timestamp);
}
if (inv->description)
json_add_string(response, "description", inv->description);

View file

@ -416,6 +416,7 @@ static void onchain_error(struct channel *channel,
struct per_peer_state *pps UNUSED,
const struct channel_id *channel_id UNUSED,
const char *desc,
bool soft_error UNUSED,
const u8 *err_for_them UNUSED)
{
/* FIXME: re-launch? */

View file

@ -712,6 +712,7 @@ static void opening_channel_errmsg(struct uncommitted_channel *uc,
struct per_peer_state *pps,
const struct channel_id *channel_id UNUSED,
const char *desc,
bool soft_error UNUSED,
const u8 *err_for_them UNUSED)
{
/* Close fds, if any. */

View file

@ -390,6 +390,7 @@ void channel_errmsg(struct channel *channel,
struct per_peer_state *pps,
const struct channel_id *channel_id UNUSED,
const char *desc,
bool soft_error,
const u8 *err_for_them)
{
notify_disconnect(channel->peer->ld, &channel->peer->id);
@ -407,6 +408,15 @@ void channel_errmsg(struct channel *channel,
err_for_them,
tal_count(err_for_them), 0);
/* Other implementations chose to ignore errors early on. Not
* surprisingly, they now spew out spurious errors frequently,
* and we would close the channel on them. */
if (soft_error) {
channel_fail_reconnect_later(channel, "%s: (ignoring) %s",
channel->owner->name, desc);
return;
}
/* BOLT #1:
*
* A sending node:

View file

@ -78,6 +78,7 @@ void channel_errmsg(struct channel *channel,
struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *desc,
bool soft_error,
const u8 *err_for_them);
u8 *p2wpkh_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx);

View file

@ -370,9 +370,10 @@ static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[3])
char *desc;
struct per_peer_state *pps;
u8 *err_for_them;
bool soft_error;
if (!fromwire_status_peer_error(msg, msg,
&channel_id, &desc,
&channel_id, &desc, &soft_error,
&pps, &err_for_them))
return false;
@ -380,7 +381,7 @@ static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[3])
/* Don't free sd; we may be about to free channel. */
sd->channel = NULL;
sd->errcb(channel, pps, &channel_id, desc, err_for_them);
sd->errcb(channel, pps, &channel_id, desc, soft_error, err_for_them);
return true;
}
@ -561,7 +562,7 @@ static void destroy_subd(struct subd *sd)
sd->errcb(channel, NULL, NULL,
tal_fmt(sd, "Owning subdaemon %s died (%i)",
sd->name, status),
NULL);
false, NULL);
if (!outer_transaction)
db_commit_transaction(db);
}
@ -611,6 +612,7 @@ static struct subd *new_subd(struct lightningd *ld,
struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *desc,
bool soft_error,
const u8 *err_for_them),
void (*billboardcb)(void *channel,
bool perm,
@ -701,6 +703,7 @@ struct subd *new_channel_subd_(struct lightningd *ld,
struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *desc,
bool soft_error,
const u8 *err_for_them),
void (*billboardcb)(void *channel, bool perm,
const char *happenings),

View file

@ -46,6 +46,7 @@ struct subd {
struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *desc,
bool soft_error,
const u8 *err_for_them);
/* Callback to display information for listpeers RPC */
@ -120,6 +121,7 @@ struct subd *new_channel_subd_(struct lightningd *ld,
struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *desc,
bool soft_error,
const u8 *err_for_them),
void (*billboardcb)(void *channel, bool perm,
const char *happenings),
@ -133,7 +135,7 @@ struct subd *new_channel_subd_(struct lightningd *ld,
(channel), \
struct per_peer_state *, \
const struct channel_id *, \
const char *, const u8 *), \
const char *, bool, const u8 *), \
typesafe_cb_postargs(void, void *, (billboardcb), \
(channel), bool, \
const char *), \

View file

@ -73,7 +73,7 @@ bool fromwire_status_fail(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, enu
bool fromwire_status_peer_billboard(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, bool *perm UNNEEDED, wirestring **happenings UNNEEDED)
{ fprintf(stderr, "fromwire_status_peer_billboard called!\n"); abort(); }
/* Generated stub for fromwire_status_peer_error */
bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct channel_id *channel UNNEEDED, wirestring **desc UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **error_for_them UNNEEDED)
bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct channel_id *channel UNNEEDED, wirestring **desc UNNEEDED, bool *soft_error UNNEEDED, struct per_peer_state **pps UNNEEDED, u8 **error_for_them UNNEEDED)
{ fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); }
/* Generated stub for get_log_book */
struct log_book *get_log_book(const struct log *log UNNEEDED)