mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-18 14:44:22 +01:00
dual-fund: keep track of aborted requests, seamlessly restart daemon
Clean restart of daemon after a tx-abort is a nice way to work around the 'persistent' disconnect that we t-bast noticed. Changelog-Fixed: `dualopend`: Fix behavior for tx-aborts. No longer hangs, appropriately continues re-init of RBF requests without reconnction msg exchange.
This commit is contained in:
@@ -42,6 +42,7 @@ peer_failed(struct per_peer_state *pps,
|
|||||||
msg = towire_status_peer_error(NULL, channel_id,
|
msg = towire_status_peer_error(NULL, channel_id,
|
||||||
desc,
|
desc,
|
||||||
warn,
|
warn,
|
||||||
|
false,
|
||||||
msg);
|
msg);
|
||||||
peer_billboard(true, desc);
|
peer_billboard(true, desc);
|
||||||
peer_fatal_continue(take(msg), pps);
|
peer_fatal_continue(take(msg), pps);
|
||||||
@@ -80,7 +81,8 @@ void peer_failed_err(struct per_peer_state *pps,
|
|||||||
void peer_failed_received_errmsg(struct per_peer_state *pps,
|
void peer_failed_received_errmsg(struct per_peer_state *pps,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
const struct channel_id *channel_id,
|
const struct channel_id *channel_id,
|
||||||
bool warning)
|
bool warning,
|
||||||
|
bool abort_restart)
|
||||||
{
|
{
|
||||||
u8 *msg;
|
u8 *msg;
|
||||||
|
|
||||||
@@ -94,7 +96,7 @@ void peer_failed_received_errmsg(struct per_peer_state *pps,
|
|||||||
warning = true;
|
warning = true;
|
||||||
}
|
}
|
||||||
msg = towire_status_peer_error(NULL, channel_id, desc, warning,
|
msg = towire_status_peer_error(NULL, channel_id, desc, warning,
|
||||||
NULL);
|
abort_restart, NULL);
|
||||||
peer_billboard(true, "Received %s", desc);
|
peer_billboard(true, "Received %s", desc);
|
||||||
peer_fatal_continue(take(msg), pps);
|
peer_fatal_continue(take(msg), pps);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ void peer_failed_err(struct per_peer_state *pps,
|
|||||||
void peer_failed_received_errmsg(struct per_peer_state *pps,
|
void peer_failed_received_errmsg(struct per_peer_state *pps,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
const struct channel_id *channel_id,
|
const struct channel_id *channel_id,
|
||||||
bool soft_error)
|
bool soft_error,
|
||||||
|
bool abort_restart)
|
||||||
NORETURN;
|
NORETURN;
|
||||||
|
|
||||||
/* I/O error */
|
/* I/O error */
|
||||||
|
|||||||
@@ -8,5 +8,7 @@ msgdata,status_peer_error,channel,channel_id,
|
|||||||
msgdata,status_peer_error,desc,wirestring,
|
msgdata,status_peer_error,desc,wirestring,
|
||||||
# Take a deep breath, then try reconnecting to the precious little snowflake.
|
# Take a deep breath, then try reconnecting to the precious little snowflake.
|
||||||
msgdata,status_peer_error,warning,bool,
|
msgdata,status_peer_error,warning,bool,
|
||||||
|
# From an abort, no reconnect but restart daemon
|
||||||
|
msgdata,status_peer_error,abort_do_restart,bool,
|
||||||
msgdata,status_peer_error,len,u16,
|
msgdata,status_peer_error,len,u16,
|
||||||
msgdata,status_peer_error,error_for_them,u8,len
|
msgdata,status_peer_error,error_for_them,u8,len
|
||||||
|
|||||||
|
@@ -83,7 +83,7 @@ bool handle_peer_error(struct per_peer_state *pps,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* We hang up when a warning is received. */
|
/* We hang up when a warning is received. */
|
||||||
peer_failed_received_errmsg(pps, err, channel_id, warning);
|
peer_failed_received_errmsg(pps, err, channel_id, warning, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ char *sanitize_error(const tal_t *ctx, const u8 *errmsg,
|
|||||||
else if (fromwire_warning(ctx, errmsg, channel_id, &data))
|
else if (fromwire_warning(ctx, errmsg, channel_id, &data))
|
||||||
warning = true;
|
warning = true;
|
||||||
else if (fromwire_tx_abort(ctx, errmsg, channel_id, &data))
|
else if (fromwire_tx_abort(ctx, errmsg, channel_id, &data))
|
||||||
warning = false;
|
warning = true;
|
||||||
else
|
else
|
||||||
return tal_fmt(ctx, "Invalid ERROR message '%s'",
|
return tal_fmt(ctx, "Invalid ERROR message '%s'",
|
||||||
tal_hex(ctx, errmsg));
|
tal_hex(ctx, errmsg));
|
||||||
|
|||||||
@@ -1820,6 +1820,8 @@ static void handle_channel_locked(struct subd *dualopend,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void dualopen_tell_depth(struct subd *dualopend,
|
void dualopen_tell_depth(struct subd *dualopend,
|
||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
const struct bitcoin_txid *txid,
|
const struct bitcoin_txid *txid,
|
||||||
@@ -2312,6 +2314,33 @@ json_openchannel_abort(struct command *cmd,
|
|||||||
return command_still_pending(cmd);
|
return command_still_pending(cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static char *restart_dualopend(const tal_t *ctx, const struct lightningd *ld,
|
||||||
|
struct channel *channel, bool from_abort)
|
||||||
|
{
|
||||||
|
int fds[2];
|
||||||
|
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
|
||||||
|
log_broken(channel->log,
|
||||||
|
"Failed to create socketpair: %s",
|
||||||
|
strerror(errno));
|
||||||
|
return tal_fmt(ctx, "Unable to create socket: %s",
|
||||||
|
strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!peer_restart_dualopend(channel->peer,
|
||||||
|
new_peer_fd(tmpctx, fds[0]),
|
||||||
|
channel, from_abort)) {
|
||||||
|
close(fds[1]);
|
||||||
|
return tal_fmt(ctx, "Peer not connected");
|
||||||
|
}
|
||||||
|
subd_send_msg(ld->connectd,
|
||||||
|
take(towire_connectd_peer_connect_subd(NULL,
|
||||||
|
&channel->peer->id,
|
||||||
|
channel->peer->connectd_counter,
|
||||||
|
&channel->cid)));
|
||||||
|
subd_send_fd(ld->connectd, fds[1]);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static struct command_result *
|
static struct command_result *
|
||||||
json_openchannel_bump(struct command *cmd,
|
json_openchannel_bump(struct command *cmd,
|
||||||
const char *buffer,
|
const char *buffer,
|
||||||
@@ -2404,29 +2433,10 @@ json_openchannel_bump(struct command *cmd,
|
|||||||
/* It's possible that the last open failed/was aborted.
|
/* It's possible that the last open failed/was aborted.
|
||||||
* So now we restart the attempt! */
|
* So now we restart the attempt! */
|
||||||
if (!channel->owner) {
|
if (!channel->owner) {
|
||||||
int fds[2];
|
char *err = restart_dualopend(cmd, cmd->ld, channel, false);
|
||||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
|
if (err)
|
||||||
log_broken(channel->log,
|
|
||||||
"Failed to create socketpair: %s",
|
|
||||||
strerror(errno));
|
|
||||||
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
||||||
"Unable to create socket: %s",
|
"%s", err);
|
||||||
strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!peer_restart_dualopend(channel->peer,
|
|
||||||
new_peer_fd(tmpctx, fds[0]),
|
|
||||||
channel)) {
|
|
||||||
close(fds[1]);
|
|
||||||
return command_fail(cmd, FUNDING_PEER_NOT_CONNECTED,
|
|
||||||
"Peer not connected.");
|
|
||||||
}
|
|
||||||
subd_send_msg(cmd->ld->connectd,
|
|
||||||
take(towire_connectd_peer_connect_subd(NULL,
|
|
||||||
&channel->peer->id,
|
|
||||||
channel->peer->connectd_counter,
|
|
||||||
&channel->cid)));
|
|
||||||
subd_send_fd(cmd->ld->connectd, fds[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->open_attempt)
|
if (channel->open_attempt)
|
||||||
@@ -3574,6 +3584,103 @@ AUTODATA(json_command, &openchannel_signed_command);
|
|||||||
AUTODATA(json_command, &openchannel_bump_command);
|
AUTODATA(json_command, &openchannel_bump_command);
|
||||||
AUTODATA(json_command, &openchannel_abort_command);
|
AUTODATA(json_command, &openchannel_abort_command);
|
||||||
|
|
||||||
|
void static dualopen_errmsg(struct channel *channel,
|
||||||
|
struct peer_fd *peer_fd,
|
||||||
|
const struct channel_id *channel_id UNUSED,
|
||||||
|
const char *desc,
|
||||||
|
bool warning,
|
||||||
|
bool aborted,
|
||||||
|
const u8 *err_for_them)
|
||||||
|
{
|
||||||
|
/* Clean up any in-progress open attempts */
|
||||||
|
channel_cleanup_commands(channel, desc);
|
||||||
|
|
||||||
|
if (channel_unsaved(channel)) {
|
||||||
|
log_info(channel->log, "%s", "Unsaved peer failed."
|
||||||
|
" Deleting channel.");
|
||||||
|
delete_channel(channel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No peer_fd means a subd crash or disconnection. */
|
||||||
|
if (!peer_fd) {
|
||||||
|
/* If the channel is unsaved, we forget it */
|
||||||
|
channel_fail_transient(channel, "%s: %s",
|
||||||
|
channel->owner->name, desc);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Do we have an error to send? */
|
||||||
|
if (err_for_them && !channel->error && !warning)
|
||||||
|
channel->error = tal_dup_talarr(channel, u8, err_for_them);
|
||||||
|
|
||||||
|
/* 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. We now support warnings
|
||||||
|
* for this case. */
|
||||||
|
if (warning || aborted) {
|
||||||
|
channel_fail_transient(channel, "%s %s: %s",
|
||||||
|
channel->owner->name,
|
||||||
|
warning ? "WARNING" : "ABORTED",
|
||||||
|
desc);
|
||||||
|
|
||||||
|
if (aborted) {
|
||||||
|
char *err = restart_dualopend(tmpctx,
|
||||||
|
channel->peer->ld,
|
||||||
|
channel, true);
|
||||||
|
if (err)
|
||||||
|
log_broken(channel->log,
|
||||||
|
"Unable to restart dualopend"
|
||||||
|
" after abort: %s", err);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* BOLT #1:
|
||||||
|
*
|
||||||
|
* A sending node:
|
||||||
|
*...
|
||||||
|
* - when sending `error`:
|
||||||
|
* - MUST fail the channel(s) referred to by the error message.
|
||||||
|
* - MAY set `channel_id` to all zero to indicate all channels.
|
||||||
|
*/
|
||||||
|
/* FIXME: Close if it's an all-channels error sent or rcvd */
|
||||||
|
|
||||||
|
/* BOLT #1:
|
||||||
|
*
|
||||||
|
* A sending node:
|
||||||
|
*...
|
||||||
|
* - when sending `error`:
|
||||||
|
* - MUST fail the channel(s) referred to by the error message.
|
||||||
|
* - MAY set `channel_id` to all zero to indicate all channels.
|
||||||
|
*...
|
||||||
|
* The receiving node:
|
||||||
|
* - upon receiving `error`:
|
||||||
|
* - if `channel_id` is all zero:
|
||||||
|
* - MUST fail all channels with the sending node.
|
||||||
|
* - otherwise:
|
||||||
|
* - MUST fail the channel referred to by `channel_id`, if that channel is with the
|
||||||
|
* sending node.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* FIXME: We don't close all channels */
|
||||||
|
/* We should immediately forget the channel if we receive error during
|
||||||
|
* CHANNELD_AWAITING_LOCKIN if we are fundee. */
|
||||||
|
if (!err_for_them && channel->opener == 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,
|
||||||
|
err_for_them ? REASON_LOCAL : REASON_PROTOCOL,
|
||||||
|
"%s: %s ERROR %s",
|
||||||
|
channel->owner->name,
|
||||||
|
err_for_them ? "sent" : "received", desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
bool peer_start_dualopend(struct peer *peer,
|
bool peer_start_dualopend(struct peer *peer,
|
||||||
struct peer_fd *peer_fd,
|
struct peer_fd *peer_fd,
|
||||||
struct channel *channel)
|
struct channel *channel)
|
||||||
@@ -3596,7 +3703,7 @@ bool peer_start_dualopend(struct peer *peer,
|
|||||||
channel->log, true,
|
channel->log, true,
|
||||||
dualopend_wire_name,
|
dualopend_wire_name,
|
||||||
dual_opend_msg,
|
dual_opend_msg,
|
||||||
channel_errmsg,
|
dualopen_errmsg,
|
||||||
channel_set_billboard,
|
channel_set_billboard,
|
||||||
take(&peer_fd->fd),
|
take(&peer_fd->fd),
|
||||||
take(&hsmfd), NULL);
|
take(&hsmfd), NULL);
|
||||||
@@ -3641,7 +3748,8 @@ bool peer_start_dualopend(struct peer *peer,
|
|||||||
|
|
||||||
bool peer_restart_dualopend(struct peer *peer,
|
bool peer_restart_dualopend(struct peer *peer,
|
||||||
struct peer_fd *peer_fd,
|
struct peer_fd *peer_fd,
|
||||||
struct channel *channel)
|
struct channel *channel,
|
||||||
|
bool from_abort)
|
||||||
{
|
{
|
||||||
u32 max_to_self_delay, blockheight;
|
u32 max_to_self_delay, blockheight;
|
||||||
struct amount_msat min_effective_htlc_capacity;
|
struct amount_msat min_effective_htlc_capacity;
|
||||||
@@ -3667,7 +3775,7 @@ bool peer_restart_dualopend(struct peer *peer,
|
|||||||
channel->log, true,
|
channel->log, true,
|
||||||
dualopend_wire_name,
|
dualopend_wire_name,
|
||||||
dual_opend_msg,
|
dual_opend_msg,
|
||||||
channel_errmsg,
|
dualopen_errmsg,
|
||||||
channel_set_billboard,
|
channel_set_billboard,
|
||||||
take(&peer_fd->fd),
|
take(&peer_fd->fd),
|
||||||
take(&hsmfd), NULL));
|
take(&hsmfd), NULL));
|
||||||
@@ -3706,6 +3814,7 @@ bool peer_restart_dualopend(struct peer *peer,
|
|||||||
|
|
||||||
msg = towire_dualopend_reinit(NULL,
|
msg = towire_dualopend_reinit(NULL,
|
||||||
chainparams,
|
chainparams,
|
||||||
|
from_abort,
|
||||||
peer->ld->our_features,
|
peer->ld->our_features,
|
||||||
peer->their_features,
|
peer->their_features,
|
||||||
&channel->our_config,
|
&channel->our_config,
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ bool peer_start_dualopend(struct peer *peer, struct peer_fd *peer_fd,
|
|||||||
|
|
||||||
bool peer_restart_dualopend(struct peer *peer,
|
bool peer_restart_dualopend(struct peer *peer,
|
||||||
struct peer_fd *peer_fd,
|
struct peer_fd *peer_fd,
|
||||||
struct channel *channel);
|
struct channel *channel,
|
||||||
|
bool from_abort);
|
||||||
|
|
||||||
void dualopen_tell_depth(struct subd *dualopend,
|
void dualopen_tell_depth(struct subd *dualopend,
|
||||||
struct channel *channel,
|
struct channel *channel,
|
||||||
|
|||||||
@@ -1496,6 +1496,7 @@ static void onchain_error(struct channel *channel,
|
|||||||
const struct channel_id *channel_id UNUSED,
|
const struct channel_id *channel_id UNUSED,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning UNUSED,
|
bool warning UNUSED,
|
||||||
|
bool aborted UNUSED,
|
||||||
const u8 *err_for_them UNUSED)
|
const u8 *err_for_them UNUSED)
|
||||||
{
|
{
|
||||||
channel_set_owner(channel, NULL);
|
channel_set_owner(channel, NULL);
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ void opend_channel_errmsg(struct uncommitted_channel *uc,
|
|||||||
const struct channel_id *channel_id UNUSED,
|
const struct channel_id *channel_id UNUSED,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning UNUSED,
|
bool warning UNUSED,
|
||||||
|
bool aborted UNUSED,
|
||||||
const u8 *err_for_them UNUSED)
|
const u8 *err_for_them UNUSED)
|
||||||
{
|
{
|
||||||
/* Close fds, if any. */
|
/* Close fds, if any. */
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ void opend_channel_errmsg(struct uncommitted_channel *uc,
|
|||||||
const struct channel_id *channel_id UNUSED,
|
const struct channel_id *channel_id UNUSED,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning UNUSED,
|
bool warning UNUSED,
|
||||||
|
bool aborted UNUSED,
|
||||||
const u8 *err_for_them UNUSED);
|
const u8 *err_for_them UNUSED);
|
||||||
|
|
||||||
void opend_channel_set_billboard(struct uncommitted_channel *uc,
|
void opend_channel_set_billboard(struct uncommitted_channel *uc,
|
||||||
|
|||||||
@@ -375,6 +375,7 @@ void channel_errmsg(struct channel *channel,
|
|||||||
const struct channel_id *channel_id UNUSED,
|
const struct channel_id *channel_id UNUSED,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning,
|
bool warning,
|
||||||
|
bool aborted UNUSED,
|
||||||
const u8 *err_for_them)
|
const u8 *err_for_them)
|
||||||
{
|
{
|
||||||
/* Clean up any in-progress open attempts */
|
/* Clean up any in-progress open attempts */
|
||||||
@@ -404,8 +405,10 @@ void channel_errmsg(struct channel *channel,
|
|||||||
* and we would close the channel on them. We now support warnings
|
* and we would close the channel on them. We now support warnings
|
||||||
* for this case. */
|
* for this case. */
|
||||||
if (warning) {
|
if (warning) {
|
||||||
channel_fail_transient(channel, "%s WARNING: %s",
|
channel_fail_transient(channel, "%s%s: %s",
|
||||||
channel->owner->name, desc);
|
channel->owner->name,
|
||||||
|
warning ? " WARNING" : " (aborted)",
|
||||||
|
desc);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1160,7 +1163,7 @@ static void connect_activate_subd(struct lightningd *ld, struct channel *channel
|
|||||||
}
|
}
|
||||||
if (peer_restart_dualopend(channel->peer,
|
if (peer_restart_dualopend(channel->peer,
|
||||||
new_peer_fd(tmpctx, fds[0]),
|
new_peer_fd(tmpctx, fds[0]),
|
||||||
channel))
|
channel, false))
|
||||||
goto tell_connectd;
|
goto tell_connectd;
|
||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
return;
|
return;
|
||||||
@@ -1529,7 +1532,7 @@ void peer_spoke(struct lightningd *ld, const u8 *msg)
|
|||||||
"Trouble in paradise?");
|
"Trouble in paradise?");
|
||||||
goto send_error;
|
goto send_error;
|
||||||
}
|
}
|
||||||
if (peer_restart_dualopend(peer, new_peer_fd(tmpctx, fds[0]), channel))
|
if (peer_restart_dualopend(peer, new_peer_fd(tmpctx, fds[0]), channel, false))
|
||||||
goto tell_connectd;
|
goto tell_connectd;
|
||||||
/* FIXME: Send informative error? */
|
/* FIXME: Send informative error? */
|
||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ void channel_errmsg(struct channel *channel,
|
|||||||
const struct channel_id *channel_id,
|
const struct channel_id *channel_id,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning,
|
bool warning,
|
||||||
|
bool aborted,
|
||||||
const u8 *err_for_them);
|
const u8 *err_for_them);
|
||||||
|
|
||||||
u8 *p2wpkh_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx);
|
u8 *p2wpkh_for_keyidx(const tal_t *ctx, struct lightningd *ld, u64 keyidx);
|
||||||
|
|||||||
@@ -425,17 +425,18 @@ static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[1])
|
|||||||
struct peer_fd *peer_fd;
|
struct peer_fd *peer_fd;
|
||||||
u8 *err_for_them;
|
u8 *err_for_them;
|
||||||
bool warning;
|
bool warning;
|
||||||
|
bool aborted;
|
||||||
|
|
||||||
if (!fromwire_status_peer_error(msg, msg,
|
if (!fromwire_status_peer_error(msg, msg,
|
||||||
&channel_id, &desc, &warning,
|
&channel_id, &desc, &warning,
|
||||||
&err_for_them))
|
&aborted, &err_for_them))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
peer_fd = new_peer_fd_arr(msg, fds);
|
peer_fd = new_peer_fd_arr(msg, fds);
|
||||||
|
|
||||||
/* Don't free sd; we may be about to free channel. */
|
/* Don't free sd; we may be about to free channel. */
|
||||||
sd->channel = NULL;
|
sd->channel = NULL;
|
||||||
sd->errcb(channel, peer_fd, &channel_id, desc, warning, err_for_them);
|
sd->errcb(channel, peer_fd, &channel_id, desc, warning, aborted, err_for_them);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -648,7 +649,7 @@ static void destroy_subd(struct subd *sd)
|
|||||||
sd->errcb(channel, NULL, NULL,
|
sd->errcb(channel, NULL, NULL,
|
||||||
tal_fmt(sd, "Owning subdaemon %s died (%i)",
|
tal_fmt(sd, "Owning subdaemon %s died (%i)",
|
||||||
sd->name, status),
|
sd->name, status),
|
||||||
false, NULL);
|
false, false, NULL);
|
||||||
if (!outer_transaction)
|
if (!outer_transaction)
|
||||||
db_commit_transaction(db);
|
db_commit_transaction(db);
|
||||||
}
|
}
|
||||||
@@ -706,6 +707,7 @@ static struct subd *new_subd(const tal_t *ctx,
|
|||||||
const struct channel_id *channel_id,
|
const struct channel_id *channel_id,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning,
|
bool warning,
|
||||||
|
bool aborted,
|
||||||
const u8 *err_for_them),
|
const u8 *err_for_them),
|
||||||
void (*billboardcb)(void *channel,
|
void (*billboardcb)(void *channel,
|
||||||
bool perm,
|
bool perm,
|
||||||
@@ -816,6 +818,7 @@ struct subd *new_channel_subd_(const tal_t *ctx,
|
|||||||
const struct channel_id *channel_id,
|
const struct channel_id *channel_id,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning,
|
bool warning,
|
||||||
|
bool aborted,
|
||||||
const u8 *err_for_them),
|
const u8 *err_for_them),
|
||||||
void (*billboardcb)(void *channel, bool perm,
|
void (*billboardcb)(void *channel, bool perm,
|
||||||
const char *happenings),
|
const char *happenings),
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ struct subd {
|
|||||||
const struct channel_id *channel_id,
|
const struct channel_id *channel_id,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning,
|
bool warning,
|
||||||
|
bool aborted,
|
||||||
const u8 *err_for_them);
|
const u8 *err_for_them);
|
||||||
|
|
||||||
/* Callback to display information for listpeers RPC */
|
/* Callback to display information for listpeers RPC */
|
||||||
@@ -136,6 +137,7 @@ struct subd *new_channel_subd_(const tal_t *ctx,
|
|||||||
const struct channel_id *channel_id,
|
const struct channel_id *channel_id,
|
||||||
const char *desc,
|
const char *desc,
|
||||||
bool warning,
|
bool warning,
|
||||||
|
bool aborted,
|
||||||
const u8 *err_for_them),
|
const u8 *err_for_them),
|
||||||
void (*billboardcb)(void *channel, bool perm,
|
void (*billboardcb)(void *channel, bool perm,
|
||||||
const char *happenings),
|
const char *happenings),
|
||||||
@@ -151,7 +153,7 @@ struct subd *new_channel_subd_(const tal_t *ctx,
|
|||||||
(channel), \
|
(channel), \
|
||||||
struct peer_fd *, \
|
struct peer_fd *, \
|
||||||
const struct channel_id *, \
|
const struct channel_id *, \
|
||||||
const char *, bool, const u8 *), \
|
const char *, bool, bool, const u8 *), \
|
||||||
typesafe_cb_postargs(void, void *, (billboardcb), \
|
typesafe_cb_postargs(void, void *, (billboardcb), \
|
||||||
(channel), bool, \
|
(channel), bool, \
|
||||||
const char *), \
|
const char *), \
|
||||||
|
|||||||
@@ -84,7 +84,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)
|
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(); }
|
{ fprintf(stderr, "fromwire_status_peer_billboard called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_status_peer_error */
|
/* 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, bool *warning 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 *warning UNNEEDED, bool *abort_do_restart UNNEEDED, u8 **error_for_them UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_status_version */
|
/* Generated stub for fromwire_status_version */
|
||||||
bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **version UNNEEDED)
|
bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **version UNNEEDED)
|
||||||
|
|||||||
@@ -796,7 +796,8 @@ struct channel *peer_any_active_channel(struct peer *peer UNNEEDED, bool *others
|
|||||||
/* Generated stub for peer_restart_dualopend */
|
/* Generated stub for peer_restart_dualopend */
|
||||||
bool peer_restart_dualopend(struct peer *peer UNNEEDED,
|
bool peer_restart_dualopend(struct peer *peer UNNEEDED,
|
||||||
struct peer_fd *peer_fd UNNEEDED,
|
struct peer_fd *peer_fd UNNEEDED,
|
||||||
struct channel *channel UNNEEDED)
|
struct channel *channel UNNEEDED,
|
||||||
|
bool from_abort UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_restart_dualopend called!\n"); abort(); }
|
{ fprintf(stderr, "peer_restart_dualopend called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_channeld */
|
/* Generated stub for peer_start_channeld */
|
||||||
bool peer_start_channeld(struct channel *channel UNNEEDED,
|
bool peer_start_channeld(struct channel *channel UNNEEDED,
|
||||||
|
|||||||
@@ -70,7 +70,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)
|
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(); }
|
{ fprintf(stderr, "fromwire_status_peer_billboard called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_status_peer_error */
|
/* 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, bool *warning 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 *warning UNNEEDED, bool *abort_do_restart UNNEEDED, u8 **error_for_them UNNEEDED)
|
||||||
{ fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); }
|
{ fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); }
|
||||||
/* Generated stub for fromwire_status_version */
|
/* Generated stub for fromwire_status_version */
|
||||||
bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **version UNNEEDED)
|
bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **version UNNEEDED)
|
||||||
|
|||||||
@@ -326,13 +326,13 @@ static bool shutdown_complete(const struct state *state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* They failed the open with us */
|
/* They failed the open with us */
|
||||||
static void negotiation_aborted(struct state *state, const char *why)
|
static void negotiation_aborted(struct state *state, const char *why, bool aborted)
|
||||||
{
|
{
|
||||||
status_debug("aborted opening negotiation: %s", why);
|
status_debug("aborted opening negotiation: %s", why);
|
||||||
|
|
||||||
/* Tell master that funding failed. */
|
/* Tell master that funding failed. */
|
||||||
peer_failed_received_errmsg(state->pps, why,
|
peer_failed_received_errmsg(state->pps, why,
|
||||||
&state->channel_id, true);
|
&state->channel_id, true, aborted);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Softer version of 'warning' (we don't disconnect)
|
/* Softer version of 'warning' (we don't disconnect)
|
||||||
@@ -1269,7 +1269,7 @@ static void handle_tx_abort(struct state *state, u8 *msg)
|
|||||||
} else
|
} else
|
||||||
desc = state->aborted_err;
|
desc = state->aborted_err;
|
||||||
|
|
||||||
negotiation_aborted(state, desc);
|
negotiation_aborted(state, desc, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 *handle_channel_ready(struct state *state, u8 *msg)
|
static u8 *handle_channel_ready(struct state *state, u8 *msg)
|
||||||
@@ -1352,7 +1352,7 @@ static u8 *opening_negotiate_msg(const tal_t *ctx, struct state *state)
|
|||||||
}
|
}
|
||||||
negotiation_aborted(state,
|
negotiation_aborted(state,
|
||||||
tal_fmt(tmpctx, "They sent %s",
|
tal_fmt(tmpctx, "They sent %s",
|
||||||
err));
|
err), false);
|
||||||
/* Return NULL so caller knows to stop negotiating. */
|
/* Return NULL so caller knows to stop negotiating. */
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@@ -4268,6 +4268,7 @@ int main(int argc, char *argv[])
|
|||||||
u8 *msg;
|
u8 *msg;
|
||||||
struct amount_sat total_funding, *requested_lease;
|
struct amount_sat total_funding, *requested_lease;
|
||||||
struct amount_msat our_msat;
|
struct amount_msat our_msat;
|
||||||
|
bool from_abort;
|
||||||
|
|
||||||
subdaemon_setup(argc, argv);
|
subdaemon_setup(argc, argv);
|
||||||
|
|
||||||
@@ -4297,6 +4298,7 @@ int main(int argc, char *argv[])
|
|||||||
/*~ Initially we're not associated with a channel, but
|
/*~ Initially we're not associated with a channel, but
|
||||||
* handle_peer_gossip_or_error compares this. */
|
* handle_peer_gossip_or_error compares this. */
|
||||||
memset(&state->channel_id, 0, sizeof(state->channel_id));
|
memset(&state->channel_id, 0, sizeof(state->channel_id));
|
||||||
|
from_abort = false;
|
||||||
state->channel = NULL;
|
state->channel = NULL;
|
||||||
state->tx_state->remote_funding_sigs_rcvd = false;
|
state->tx_state->remote_funding_sigs_rcvd = false;
|
||||||
|
|
||||||
@@ -4317,6 +4319,7 @@ int main(int argc, char *argv[])
|
|||||||
state->requested_lease = NULL;
|
state->requested_lease = NULL;
|
||||||
} else if (fromwire_dualopend_reinit(state, msg,
|
} else if (fromwire_dualopend_reinit(state, msg,
|
||||||
&chainparams,
|
&chainparams,
|
||||||
|
&from_abort,
|
||||||
&state->our_features,
|
&state->our_features,
|
||||||
&state->their_features,
|
&state->their_features,
|
||||||
&state->tx_state->localconf,
|
&state->tx_state->localconf,
|
||||||
@@ -4431,7 +4434,7 @@ int main(int argc, char *argv[])
|
|||||||
pollfd[1].events = POLLIN;
|
pollfd[1].events = POLLIN;
|
||||||
|
|
||||||
/* Do reconnect, if need be */
|
/* Do reconnect, if need be */
|
||||||
if (state->channel) {
|
if (state->channel && !from_abort) {
|
||||||
do_reconnect_dance(state);
|
do_reconnect_dance(state);
|
||||||
state->reconnected = true;
|
state->reconnected = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ msgdata,dualopend_init,require_confirmed_inputs,bool,
|
|||||||
# master-dualopend: peer has reconnected
|
# master-dualopend: peer has reconnected
|
||||||
msgtype,dualopend_reinit,7001
|
msgtype,dualopend_reinit,7001
|
||||||
msgdata,dualopend_reinit,chainparams,chainparams,
|
msgdata,dualopend_reinit,chainparams,chainparams,
|
||||||
|
msgdata,dualopend_reinit,from_abort,bool,
|
||||||
msgdata,dualopend_reinit,our_feature_set,feature_set,
|
msgdata,dualopend_reinit,our_feature_set,feature_set,
|
||||||
msgdata,dualopend_reinit,their_init_features_len,u16,
|
msgdata,dualopend_reinit,their_init_features_len,u16,
|
||||||
msgdata,dualopend_reinit,their_init_features,u8,their_init_features_len
|
msgdata,dualopend_reinit,their_init_features,u8,their_init_features_len
|
||||||
|
|||||||
|
Can't render this file because it has a wrong number of fields in line 16.
|
@@ -380,7 +380,6 @@ def test_v2_rbf_single(node_factory, bitcoind, chainparams):
|
|||||||
|
|
||||||
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
|
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
|
||||||
@pytest.mark.openchannel('v2')
|
@pytest.mark.openchannel('v2')
|
||||||
@pytest.mark.xfail
|
|
||||||
def test_v2_rbf_abort_retry(node_factory, bitcoind, chainparams):
|
def test_v2_rbf_abort_retry(node_factory, bitcoind, chainparams):
|
||||||
l1, l2 = node_factory.get_nodes(2, opts={'wumbo': None,
|
l1, l2 = node_factory.get_nodes(2, opts={'wumbo': None,
|
||||||
'allow_warning': True})
|
'allow_warning': True})
|
||||||
@@ -463,7 +462,6 @@ def test_v2_rbf_abort_retry(node_factory, bitcoind, chainparams):
|
|||||||
|
|
||||||
|
|
||||||
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
|
@unittest.skipIf(TEST_NETWORK != 'regtest', 'elementsd doesnt yet support PSBT features we need')
|
||||||
@pytest.mark.xfail
|
|
||||||
@pytest.mark.openchannel('v2')
|
@pytest.mark.openchannel('v2')
|
||||||
def test_v2_rbf_abort_channel_opens(node_factory, bitcoind, chainparams):
|
def test_v2_rbf_abort_channel_opens(node_factory, bitcoind, chainparams):
|
||||||
l1, l2 = node_factory.get_nodes(2, opts={'wumbo': None,
|
l1, l2 = node_factory.get_nodes(2, opts={'wumbo': None,
|
||||||
|
|||||||
@@ -629,7 +629,8 @@ void payment_succeeded(struct lightningd *ld UNNEEDED,
|
|||||||
/* Generated stub for peer_restart_dualopend */
|
/* Generated stub for peer_restart_dualopend */
|
||||||
bool peer_restart_dualopend(struct peer *peer UNNEEDED,
|
bool peer_restart_dualopend(struct peer *peer UNNEEDED,
|
||||||
struct peer_fd *peer_fd UNNEEDED,
|
struct peer_fd *peer_fd UNNEEDED,
|
||||||
struct channel *channel UNNEEDED)
|
struct channel *channel UNNEEDED,
|
||||||
|
bool from_abort UNNEEDED)
|
||||||
{ fprintf(stderr, "peer_restart_dualopend called!\n"); abort(); }
|
{ fprintf(stderr, "peer_restart_dualopend called!\n"); abort(); }
|
||||||
/* Generated stub for peer_start_channeld */
|
/* Generated stub for peer_start_channeld */
|
||||||
bool peer_start_channeld(struct channel *channel UNNEEDED,
|
bool peer_start_channeld(struct channel *channel UNNEEDED,
|
||||||
|
|||||||
Reference in New Issue
Block a user