diff --git a/channeld/channeld.c b/channeld/channeld.c index bef107c66f4e..dbc3cf705aef 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -3004,11 +3004,12 @@ static struct wally_psbt *next_splice_step(const tal_t *ctx, return ictx->desired_psbt; } -static const u8 *peer_expect_msg_three(const tal_t *ctx, +static const u8 *peer_expect_msg_four(const tal_t *ctx, struct peer *peer, enum peer_wire expect_type, enum peer_wire second_allowed_type, - enum peer_wire third_allowed_type) + enum peer_wire third_allowed_type, + enum peer_wire fourth_allowed_type) { u8 *msg; enum peer_wire type; @@ -3019,14 +3020,22 @@ static const u8 *peer_expect_msg_three(const tal_t *ctx, && type != third_allowed_type) peer_failed_warn(peer->pps, &peer->channel_id, "Got incorrect message from peer: %s" - " (should be %s) [%s]", + " (should be %s or %s or %s of %s) [%s]", peer_wire_name(type), peer_wire_name(expect_type), + peer_wire_name(second_allowed_type), + peer_wire_name(third_allowed_type), + peer_wire_name(fourth_allowed_type), sanitize_error(tmpctx, msg, &peer->channel_id)); return msg; } +/* In some circumstances Eclair send CHANNEL_READY after CHANNEL_REESTABLISH but + * before resuming splice negotiation, so we need a way to process it in this + * order. */ +static void peer_in(struct peer *peer, const u8 *msg); + /* The question of "who signs splice commitments first" is the same order as the * splice `tx_signature`s are. This function handles sending & receiving the * required commitments as part of the splicing process. @@ -3038,7 +3047,8 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, size_t inflight_index, bool send_commitments, bool recv_commitments, - const u8 **msg_received) + const u8 **msg_received, + int allowed_premature_msg) { struct commitsig_info *result; const u8 *msg; @@ -3080,10 +3090,21 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, result = NULL; if (recv_commitments) { - msg = peer_expect_msg_three(tmpctx, peer, - WIRE_COMMITMENT_SIGNED, - WIRE_TX_SIGNATURES, - WIRE_TX_ABORT); + msg = peer_expect_msg_four(tmpctx, peer, + WIRE_COMMITMENT_SIGNED, + WIRE_TX_SIGNATURES, + WIRE_TX_ABORT, + allowed_premature_msg); + + if (allowed_premature_msg + && fromwire_peektype(msg) == allowed_premature_msg) { + peer_in(peer, msg); + msg = peer_expect_msg_four(tmpctx, peer, + WIRE_COMMITMENT_SIGNED, + WIRE_TX_SIGNATURES, + WIRE_TX_ABORT, + 0); + } check_tx_abort(peer, msg, &inflight->outpoint.txid); @@ -3633,7 +3654,8 @@ static void resume_splice_negotiation(struct peer *peer, bool send_commitments, bool recv_commitments, bool send_signature, - bool recv_signature) + bool recv_signature, + int allowed_premature_msg) { struct inflight *inflight = last_inflight(peer); enum tx_role our_role = inflight->i_am_initiator @@ -3692,7 +3714,8 @@ static void resume_splice_negotiation(struct peer *peer, last_inflight_index(peer), send_commitments, recv_commitments, - &msg_received); + &msg_received, + allowed_premature_msg); check_tx_abort(peer, msg_received, &inflight->outpoint.txid); @@ -4250,7 +4273,7 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) peer->splice_state->count++; - resume_splice_negotiation(peer, true, true, true, true); + resume_splice_negotiation(peer, true, true, true, true, 0); } /* splice_initiator runs when splice_ack is received by the other side. It @@ -4556,7 +4579,7 @@ static void splice_initiator_user_finalized(struct peer *peer) their_commit = interactive_send_commitments(peer, new_inflight->psbt, our_role, last_inflight_index(peer), - true, true, NULL); + true, true, NULL, 0); new_inflight->last_tx = tal_steal(new_inflight, their_commit->tx); new_inflight->last_sig = their_commit->commit_signature; @@ -4572,7 +4595,7 @@ static void splice_initiator_user_finalized(struct peer *peer) peer->splicing->force_sign_first); if (!sign_first) - resume_splice_negotiation(peer, false, false, false, true); + resume_splice_negotiation(peer, false, false, false, true, 0); outmsg = towire_channeld_splice_confirmed_update(NULL, new_inflight->psbt, @@ -4773,7 +4796,7 @@ static void splice_initiator_user_signed(struct peer *peer, const u8 *inmsg) audit_psbt(inflight->psbt, inflight->psbt); assert(tal_parent(inflight->psbt) != tmpctx); - resume_splice_negotiation(peer, false, false, true, sign_first); + resume_splice_negotiation(peer, false, false, true, sign_first, 0); audit_psbt(inflight->psbt, inflight->psbt); assert(tal_parent(inflight->psbt) != tmpctx); @@ -5705,6 +5728,8 @@ static void peer_reconnect(struct peer *peer, do { clean_tmpctx(); msg = peer_read(tmpctx, peer->pps); + check_tx_abort(peer, msg, + inflight ? &inflight->outpoint.txid : NULL); } while (handle_peer_error_or_warning(peer->pps, msg) || capture_premature_msg(&premature_msgs, msg)); @@ -5757,7 +5782,8 @@ static void peer_reconnect(struct peer *peer, false, !inflight->last_tx, false, - true); + true, + WIRE_CHANNEL_READY); } else if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid, &inflight->outpoint.txid)) { /* Don't send sigs unless we have theirs */ @@ -5773,7 +5799,8 @@ static void peer_reconnect(struct peer *peer, : false, local_next_funding && !inflight->last_tx, true, - local_next_funding); + local_next_funding, + WIRE_CHANNEL_READY); } else if (bitcoin_txid_eq(&remote_next_funding->next_funding_txid, &peer->channel->funding.txid)) { peer_failed_err(peer->pps, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 627e43604cbc..e01a3233a096 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -482,7 +482,6 @@ static void handle_splice_lookup_tx(struct lightningd *ld, /* Extra splice data we want to store for bitcoin send tx interface */ struct send_splice_info { - struct splice_command *cc; struct channel *channel; const struct bitcoin_tx *final_tx; u32 output_index; @@ -497,6 +496,7 @@ static void handle_tx_broadcast(struct send_splice_info *info) struct bitcoin_txid txid; u8 *tx_bytes; int num_utxos; + struct splice_command *cc; tx_bytes = linearize_tx(tmpctx, info->final_tx); bitcoin_txid(info->final_tx, &txid); @@ -508,15 +508,17 @@ static void handle_tx_broadcast(struct send_splice_info *info) if (num_utxos) wallet_transaction_add(ld->wallet, info->final_tx->wtx, 0, 0); - if (info->cc) { - response = json_stream_success(info->cc->cmd); + cc = splice_command_for_chan(ld, info->channel); + + if (cc) { + response = json_stream_success(cc->cmd); json_add_hex(response, "tx", tx_bytes, tal_bytelen(tx_bytes)); json_add_txid(response, "txid", &txid); json_add_u32(response, "outnum", info->output_index); json_add_psbt(response, "psbt", info->psbt); - was_pending(command_success(info->cc->cmd, response)); + was_pending(command_success(cc->cmd, response)); } } @@ -527,25 +529,32 @@ static void check_utxo_block(struct bitcoind *bitcoind UNUSED, void *arg) { struct send_splice_info *info = arg; + struct lightningd *ld = info->channel->peer->ld; + struct splice_command *cc; if(!txout) { - if (info->cc) - was_pending(command_fail(info->cc->cmd, + cc = splice_command_for_chan(ld, info->channel); + if (cc) + was_pending(command_fail(cc->cmd, SPLICE_BROADCAST_FAIL, - "Error broadcasting splice " - "tx: %s. Unsent tx discarded " - "%s.", + "Error broadcasting splice" + " %s. Unsent tx discarded" + " %s.", info->err_msg, - fmt_wally_tx(tmpctx, - info->final_tx->wtx))); + info->final_tx && info->final_tx->wtx ? + fmt_wally_tx(tmpctx, + info->final_tx->wtx) + : "NULL")); log_unusual(info->channel->log, - "Error broadcasting splice " - "tx: %s. Unsent tx discarded " - "%s.", + "Error broadcasting splice" + " %s. Unsent tx discarded" + " %s.", info->err_msg, - fmt_wally_tx(tmpctx, - info->final_tx->wtx)); + info->final_tx && info->final_tx->wtx ? + fmt_wally_tx(tmpctx, + info->final_tx->wtx) + : "NULL"); } else handle_tx_broadcast(info); @@ -558,8 +567,6 @@ static void send_splice_tx_done(struct bitcoind *bitcoind UNUSED, bool success, const char *msg, struct send_splice_info *info) { - /* A NULL value of `info->cc` means we got here without user intiation. - * This means we are the ACCEPTER side of the splice */ struct lightningd *ld = info->channel->peer->ld; struct bitcoin_outpoint outpoint; @@ -593,7 +600,6 @@ static void send_splice_tx(struct channel *channel, struct send_splice_info *info = tal(NULL, struct send_splice_info); - info->cc = tal_steal(info, cc); info->channel = channel; info->final_tx = tal_steal(info, tx); info->output_index = output_index;