lightningd: Add tx_abort routine to lightningd

Lightningd is responsible to restart channeld when it gets this message.
This commit is contained in:
Dusty Daemon 2024-01-22 18:06:03 -05:00 committed by Christian Decker
parent 0519cd4256
commit 5e325d8880
4 changed files with 105 additions and 5 deletions

View File

@ -10,6 +10,7 @@
#include <common/derive_basepoints.h>
#include <common/features.h>
#include <common/fee_states.h>
#include <wire/peer_wire.h>
# Begin! (passes gossipd-client fd)
msgtype,channeld_init,1000
@ -280,6 +281,12 @@ msgdata,channeld_splice_funding_error,opener_error,bool,
msgtype,channeld_splice_state_error,7221
msgdata,channeld_splice_state_error,state_error,wirestring,
# channeld->master: Peer rejected our splice
msgtype,channeld_splice_abort,7223
msgdata,channeld_splice_abort,did_i_initiate,bool,
msgdata,channeld_splice_abort,inflight_outpoint,?bitcoin_outpoint,
msgdata,channeld_splice_abort,reason,?wirestring,
# Tell peer to shut down channel.
msgtype,channeld_send_shutdown,1023
msgdata,channeld_send_shutdown,final_index,?u32,

Can't render this file because it has a wrong number of fields in line 16.

View File

@ -77,6 +77,7 @@ enum jsonrpc_errcode {
SPLICE_STATE_ERROR = 358,
SPLICE_LOW_FEE = 359,
SPLICE_HIGH_FEE = 360,
SPLICE_ABORT = 362,
/* `connect` errors */
CONNECT_NO_KNOWN_ADDRESS = 400,

View File

@ -84,17 +84,17 @@ char *sanitize_error(const tal_t *ctx, const u8 *errmsg,
struct channel_id dummy;
u8 *data;
size_t i;
bool warning;
char *tag;
if (!channel_id)
channel_id = &dummy;
if (fromwire_error(ctx, errmsg, channel_id, &data))
warning = false;
tag = "ERROR";
else if (fromwire_warning(ctx, errmsg, channel_id, &data))
warning = true;
tag = "WARNING";
else if (fromwire_tx_abort(ctx, errmsg, channel_id, &data))
warning = true;
tag = "ABORT";
else
return tal_fmt(ctx, "Invalid ERROR message '%s'",
tal_hex(ctx, errmsg));
@ -118,7 +118,7 @@ char *sanitize_error(const tal_t *ctx, const u8 *errmsg,
}
return tal_fmt(ctx, "%s%s%s: %.*s",
warning ? "WARNING" : "ERROR",
tag,
channel_id_is_all(channel_id) ? "": " channel ",
channel_id_is_all(channel_id) ? ""
: type_to_string(tmpctx, struct channel_id, channel_id),

View File

@ -284,6 +284,95 @@ static void handle_splice_feerate_error(struct lightningd *ld,
}
}
static void handle_splice_abort(struct lightningd *ld,
struct channel *channel,
const u8 *msg)
{
struct splice_command *cc;
struct peer *peer = channel->peer;
bool did_i_abort;
struct bitcoin_outpoint *outpoint;
struct channel_inflight *inflight;
char *reason;
u8 *error;
int fds[2];
if (!fromwire_channeld_splice_abort(tmpctx, msg, &did_i_abort,
&outpoint, &reason)) {
channel_internal_error(channel,
"bad fromwire_channeld_splice_abort %s",
tal_hex(channel, msg));
return;
}
if (outpoint) {
inflight = list_tail(&channel->inflights,
struct channel_inflight,
list);
if (!bitcoin_outpoint_eq(outpoint,
&inflight->funding->outpoint))
channel_internal_error(channel,
"abort outpoint %s does not"
" match ours %s",
type_to_string(tmpctx,
struct bitcoin_outpoint,
outpoint),
type_to_string(tmpctx,
struct bitcoin_outpoint,
&inflight->funding->outpoint));
wallet_inflight_del(ld->wallet, channel, inflight);
}
cc = splice_command_for_chan(ld, channel);
if (cc)
was_pending(command_fail(cc->cmd, SPLICE_ABORT, "%s", reason));
else
log_peer_unusual(ld->log, &peer->id, "Splice aborted"
" %s", reason);
log_debug(channel->log,
"Restarting channeld after tx_abort on %s channel",
channel_state_name(channel));
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
log_broken(channel->log,
"Failed to create socketpair: %s",
strerror(errno));
error = towire_warningfmt(tmpctx, &channel->cid,
"Trouble in paradise?");
log_peer_debug(ld->log, &channel->peer->id,
"Telling connectd to send error %s",
tal_hex(tmpctx, error));
/* Get connectd to send error and close. */
subd_send_msg(ld->connectd,
take(towire_connectd_peer_final_msg(NULL,
&peer->id,
peer->connectd_counter,
error)));
return;
}
log_debug(channel->log, "made the socket pair");
if (peer_start_channeld(channel, new_peer_fd(tmpctx, fds[0]), NULL,
true, false)) {
log_info(channel->log, "Sending the peer fd to connectd");
subd_send_msg(ld->connectd,
take(towire_connectd_peer_connect_subd(NULL,
&peer->id,
peer->connectd_counter,
&channel->cid)));
subd_send_fd(ld->connectd, fds[1]);
log_info(channel->log, "Sent the peer fd to channeld");
}
else {
log_info(channel->log, "peer_start_channeld failed");
close(fds[1]);
}
}
/* When channeld finishes processing the `splice_init` command, this is called */
static void handle_splice_confirmed_init(struct lightningd *ld,
struct channel *channel,
@ -1366,6 +1455,9 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds)
case WIRE_CHANNELD_SPLICE_FUNDING_ERROR:
handle_splice_funding_error(sd->ld, sd->channel, msg);
break;
case WIRE_CHANNELD_SPLICE_ABORT:
handle_splice_abort(sd->ld, sd->channel, msg);
break;
case WIRE_CHANNELD_SPLICE_STATE_ERROR:
handle_splice_state_error(sd->ld, sd->channel, msg);
break;