Fix: fundee can forget channel if it receives error during CHANNELD_AWAITING_LOCKIN

This commit is contained in:
trueptolemy 2019-08-27 02:31:25 +08:00 committed by neil saitug
parent a3b43fa196
commit db145f575b
3 changed files with 43 additions and 4 deletions

View File

@ -362,7 +362,7 @@ void channel_fail_permanent(struct channel *channel, const char *fmt, ...)
struct channel_id cid;
va_start(ap, fmt);
why = tal_vfmt(channel, fmt, ap);
why = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);
log_unusual(channel->log, "Peer permanent failure in %s: %s",
@ -386,6 +386,33 @@ void channel_fail_permanent(struct channel *channel, const char *fmt, ...)
tal_free(why);
}
void channel_fail_forget(struct channel *channel, const char *fmt, ...)
{
va_list ap;
char *why;
struct channel_id cid;
assert(channel->funder == REMOTE &&
channel->state == CHANNELD_AWAITING_LOCKIN);
va_start(ap, fmt);
why = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);
log_unusual(channel->log, "Peer permanent failure in %s: %s, "
"forget channel",
channel_state_name(channel), why);
if (!channel->error) {
derive_channel_id(&cid,
&channel->funding_txid,
channel->funding_outnum);
channel->error = towire_errorfmt(channel, &cid, "%s", why);
}
delete_channel(channel);
tal_free(why);
}
void channel_internal_error(struct channel *channel, const char *fmt, ...)
{
va_list ap;

View File

@ -187,6 +187,9 @@ PRINTF_FMT(2,3) void channel_fail_reconnect_later(struct channel *channel,
/* Channel has failed, give up on it. */
void channel_fail_permanent(struct channel *channel, const char *fmt, ...);
/* Forget the channel. This is only used for the case when we "receive" error
* during CHANNELD_AWAITING_LOCKIN if we are "fundee". */
void channel_fail_forget(struct channel *channel, const char *fmt, ...);
/* Permanent error, but due to internal problems, not peer. */
void channel_internal_error(struct channel *channel, const char *fmt, ...);

View File

@ -441,9 +441,18 @@ void channel_errmsg(struct channel *channel,
* - MUST fail the channel referred to by the error message,
* if that channel is with the sending node.
*/
channel_fail_permanent(channel, "%s: %s ERROR %s",
channel->owner->name,
err_for_them ? "sent" : "received", desc);
/* We should immediately forget the channel if we receive error during
* CHANNELD_AWAITING_LOCKIN if we are fundee. */
if (!err_for_them && channel->funder == REMOTE
&& channel->state == CHANNELD_AWAITING_LOCKIN)
channel_fail_forget(channel, "%s: %s ERROR %s",
channel->owner->name,
err_for_them ? "sent" : "received", desc);
else
channel_fail_permanent(channel, "%s: %s ERROR %s",
channel->owner->name,
err_for_them ? "sent" : "received", desc);
}
struct peer_connected_hook_payload {