Skip to content

Commit

Permalink
lightningd: Add tx_abort routine to lightningd
Browse files Browse the repository at this point in the history
Lightningd is responsible to restart channeld when it gets this message.
  • Loading branch information
ddustin authored and cdecker committed Feb 11, 2024
1 parent 0519cd4 commit 5e325d8
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 5 deletions.
7 changes: 7 additions & 0 deletions channeld/channeld_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down
1 change: 1 addition & 0 deletions common/jsonrpc_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
10 changes: 5 additions & 5 deletions common/wire_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -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),
Expand Down
92 changes: 92 additions & 0 deletions lightningd/channel_control.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 5e325d8

Please sign in to comment.