diff --git a/channeld/channeld.c b/channeld/channeld.c index 503f6fb605f4..c00081a78e0e 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -235,14 +235,15 @@ static void end_stfu_mode(struct peer *peer) status_debug("Left STFU mode."); } -static void maybe_send_stfu(struct peer *peer) +static bool maybe_send_stfu(struct peer *peer) { if (!peer->want_stfu) - return; + return false; if (pending_updates(peer->channel, LOCAL, false)) { status_info("Pending updates prevent us from STFU mode at this" " time."); + return false; } else if (!peer->stfu_sent[LOCAL]) { status_debug("Sending peer that we want to STFU."); @@ -269,6 +270,8 @@ static void maybe_send_stfu(struct peer *peer) peer->on_stfu_success = NULL; } } + + return true; } /* Durring reestablish, STFU mode is assumed if continuing a splice */ @@ -488,6 +491,8 @@ static void check_mutual_splice_locked(struct peer *peer) "Splice lock unable to update funding. %s", error); + peer->channel->funding_pubkey[REMOTE] = inflight->remote_funding; + status_debug("mutual splice_locked, channel updated to: %s", fmt_channel(tmpctx, peer->channel)); @@ -938,7 +943,8 @@ static struct bitcoin_signature *calc_commitsigs(const tal_t *ctx, const struct htlc **htlc_map, u64 commit_index, const struct pubkey *remote_per_commit, - struct bitcoin_signature *commit_sig) + struct bitcoin_signature *commit_sig, + struct pubkey remote_funding_pubkey) { struct simple_htlc **htlcs; size_t i; @@ -948,8 +954,8 @@ static struct bitcoin_signature *calc_commitsigs(const tal_t *ctx, htlcs = collect_htlcs(tmpctx, htlc_map); msg = towire_hsmd_sign_remote_commitment_tx(NULL, txs[0], - &peer->channel->funding_pubkey[REMOTE], - remote_per_commit, + &remote_funding_pubkey, + remote_per_commit, channel_has(peer->channel, OPT_STATIC_REMOTEKEY), commit_index, @@ -1131,7 +1137,9 @@ static u8 *send_commit_part(const tal_t *ctx, s64 remote_splice_amnt, u64 remote_index, const struct pubkey *remote_per_commit, - struct local_anchor_info **anchor) + struct local_anchor_info **anchor, + u16 batch_size, + struct pubkey remote_funding_pubkey) { u8 *msg; struct bitcoin_signature commit_sig, *htlc_sigs; @@ -1141,6 +1149,9 @@ static u8 *send_commit_part(const tal_t *ctx, struct wally_tx_output *direct_outputs[NUM_SIDES]; struct penalty_base *pbase; int local_anchor_outnum; + struct pubkey funding_pubkeys[NUM_SIDES] = + { peer->channel->funding_pubkey[LOCAL], + remote_funding_pubkey }; struct tlv_commitment_signed_tlvs *cs_tlv = tlv_commitment_signed_tlvs_new(tmpctx); @@ -1149,24 +1160,29 @@ static u8 *send_commit_part(const tal_t *ctx, * send unless negotiated */ if (feature_negotiated(peer->our_features, peer->their_features, - OPT_EXPERIMENTAL_SPLICE)) { + OPT_SPLICE)) { status_debug("send_commit_part(splice: %d, remote_splice: %d," " index: %"PRIu64")", (int)splice_amnt, (int)remote_splice_amnt, remote_index); - cs_tlv->splice_info = tal(cs_tlv, struct channel_id); - derive_channel_id(cs_tlv->splice_info, funding); + cs_tlv->splice_info = tal(cs_tlv, + struct tlv_commitment_signed_tlvs_splice_info); + + cs_tlv->splice_info->batch_size = batch_size; + derive_channel_id(&cs_tlv->splice_info->funding_txid, funding); } txs = channel_txs(tmpctx, funding, funding_sats, &htlc_map, direct_outputs, &funding_wscript, peer->channel, remote_per_commit, remote_index, REMOTE, - splice_amnt, remote_splice_amnt, &local_anchor_outnum); + splice_amnt, remote_splice_amnt, &local_anchor_outnum, + funding_pubkeys); htlc_sigs = calc_commitsigs(tmpctx, peer, txs, funding_wscript, htlc_map, - remote_index, remote_per_commit, &commit_sig); + remote_index, remote_per_commit, &commit_sig, + remote_funding_pubkey); if (direct_outputs[LOCAL] != NULL) { pbase = penalty_base_new(tmpctx, remote_index, @@ -1230,6 +1246,7 @@ static void send_commit(struct peer *peer) u32 feerate_target; u8 **msgs = tal_arr(tmpctx, u8*, 1); u8 *msg; + u16 batch_size = tal_count(peer->splice_state->inflights) + 1; struct local_anchor_info *local_anchor, *anchors_info; if (peer->dev_disable_commit && !*peer->dev_disable_commit) { @@ -1344,7 +1361,9 @@ static void send_commit(struct peer *peer) msgs[0] = send_commit_part(msgs, peer, &peer->channel->funding, peer->channel->funding_sats, changed_htlcs, true, 0, 0, peer->next_index[REMOTE], - &peer->remote_per_commit, &local_anchor); + &peer->remote_per_commit, &local_anchor, + batch_size, + peer->channel->funding_pubkey[REMOTE]); if (local_anchor) tal_arr_expand(&anchors_info, *local_anchor); @@ -1372,7 +1391,9 @@ static void send_commit(struct peer *peer) remote_splice_amnt, peer->next_index[REMOTE], &peer->remote_per_commit, - &local_anchor)); + &local_anchor, + batch_size, + peer->splice_state->inflights[i]->remote_funding)); if (local_anchor) tal_arr_expand(&anchors_info, *local_anchor); } @@ -1666,7 +1687,7 @@ static bool have_they_signed_inflight(const struct peer *peer, return has_sig; } -/* this checks if local has signed everything buy the funding input */ +/* This checks if local has signed everything but the funding input */ static bool missing_user_signatures(const struct peer *peer, const struct inflight *inflight) { @@ -1706,7 +1727,8 @@ static void check_tx_abort(struct peer *peer, const u8 *msg) struct inflight *inflight = last_inflight(peer); struct bitcoin_outpoint *outpoint; struct channel_id channel_id; - u8 *reason; + u8 *data; + char *reason; if (fromwire_peektype(msg) != WIRE_TX_ABORT) return; @@ -1718,7 +1740,7 @@ static void check_tx_abort(struct peer *peer, const u8 *msg) tal_hex(tmpctx, msg)); } - if (!fromwire_tx_abort(tmpctx, msg, &channel_id, &reason)) + if (!fromwire_tx_abort(tmpctx, msg, &channel_id, &data)) peer_failed_warn(peer->pps, &peer->channel_id, "bad tx_abort %s", tal_hex(msg, msg)); @@ -1733,10 +1755,17 @@ static void check_tx_abort(struct peer *peer, const u8 *msg) status_info("Send tx_abort to master"); + reason = sanitize_error(tmpctx, msg, &peer->channel_id); + + status_info("Peer initiated tx_abort for reason: %s", reason); + wire_sync_write(MASTER_FD, take(towire_channeld_splice_abort(NULL, false, outpoint, - (char*)reason))); + tal_fmt(tmpctx, + "Peer aborted" + " for reason: %s", + reason)))); /* Give master a chance to pass the fd along */ status_info("Delaying closing of master fd by 1 second"); @@ -1759,14 +1788,15 @@ static void splice_abort(struct peer *peer, const char *fmt, ...) va_end(ap); if (have_i_signed_inflight(peer, inflight)) - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "Tried to abort a splice where I have already" + peer_failed_err(peer->pps, &peer->channel_id, + "I needed to abort a splice where I have already" " sent my signatures"); status_info("We are initiating tx_abort for reason: %s", reason); peer_write(peer->pps, - take(towire_tx_abort(NULL, &peer->channel_id, (u8*)reason))); + take(towire_abortfmt(NULL, &peer->channel_id, "%s", + reason))); do { msg = peer_read(tmpctx, peer->pps); @@ -1814,6 +1844,7 @@ struct commitsig_info { static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, const u8 *msg, u32 commit_index, + struct pubkey remote_funding, const struct htlc **changed_htlcs, s64 splice_amnt, s64 remote_splice_amnt, @@ -1840,6 +1871,9 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, struct channel_id active_id; const struct commitsig **commitsigs; int remote_anchor_outnum; + struct pubkey funding_pubkeys[NUM_SIDES] = + { peer->channel->funding_pubkey[LOCAL], + remote_funding }; status_debug("handle_peer_commit_sig(splice: %d, remote_splice: %d," " index: %"PRIu64")", @@ -1862,10 +1896,12 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, derive_channel_id(&active_id, &peer->channel->funding); if (peer->splice_state->await_commitment_succcess && !tal_count(peer->splice_state->inflights) && cs_tlv && cs_tlv->splice_info) { - if (!channel_id_eq(&active_id, cs_tlv->splice_info)) { + if (!channel_id_eq(&active_id, + &cs_tlv->splice_info->funding_txid)) { status_info("Ignoring stale commit_sig for channel_id" " %s, as %s is locked in now.", - fmt_channel_id(tmpctx, cs_tlv->splice_info), + fmt_channel_id(tmpctx, + &cs_tlv->splice_info->funding_txid), fmt_channel_id(tmpctx, &active_id)); return NULL; } @@ -1923,11 +1959,12 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, NULL, &funding_wscript, peer->channel, local_per_commit, local_index, LOCAL, splice_amnt, - remote_splice_amnt, &remote_anchor_outnum); + remote_splice_amnt, &remote_anchor_outnum, + funding_pubkeys); /* Set the commit_sig on the commitment tx psbt */ if (!psbt_input_set_signature(txs[0]->psbt, 0, - &peer->channel->funding_pubkey[REMOTE], + &remote_funding, &commit_sig)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Unable to set signature internally"); @@ -1950,7 +1987,7 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, * `error` and fail the channel. */ if (!check_tx_sig(txs[0], 0, NULL, funding_wscript, - &peer->channel->funding_pubkey[REMOTE], &commit_sig)) { + &remote_funding, &commit_sig)) { dump_htlcs(peer->channel, "receiving commit_sig"); peer_failed_warn(peer->pps, &peer->channel_id, "Bad commit_sig signature %"PRIu64" %s for tx" @@ -1961,13 +1998,12 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, fmt_bitcoin_signature(msg, &commit_sig), fmt_bitcoin_tx(msg, txs[0]), tal_hex(msg, funding_wscript), - fmt_pubkey(msg, - &peer->channel->funding_pubkey[REMOTE]), + fmt_pubkey(msg, &remote_funding), channel_feerate(peer->channel, LOCAL), fmt_channel_id(tmpctx, &active_id), cs_tlv && cs_tlv->splice_info ? fmt_channel_id(tmpctx, - cs_tlv->splice_info) + &cs_tlv->splice_info->funding_txid) : "N/A", peer->splice_state->await_commitment_succcess ? "yes" : "no", @@ -2001,6 +2037,9 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, wscript = bitcoin_tx_output_get_witscript(tmpctx, txs[0], txs[i+1]->wtx->inputs[0].index); + /* DTODO: How does the htlc sig know the funding pubkey has changed? + * It probably doesn't even though send_commit_part does! */ + if (!check_tx_sig(txs[1+i], 0, NULL, wscript, &remote_htlckey, &htlc_sigs[i])) peer_failed_warn(peer->pps, &peer->channel_id, @@ -2080,6 +2119,7 @@ static struct commitsig_info *handle_peer_commit_sig(struct peer *peer, /* We purposely just store the last commit msg in result */ result = handle_peer_commit_sig(peer, splice_msg, i + 1, + peer->splice_state->inflights[i]->remote_funding, changed_htlcs, sub_splice_amnt, funding_diff - sub_splice_amnt, local_index, local_per_commit, @@ -2721,7 +2761,9 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, remote_splice_amnt, next_index_remote - 1, &peer->old_remote_per_commit, - &local_anchor)); + &local_anchor, + 1, + inflight->remote_funding)); } result = NULL; @@ -2750,6 +2792,7 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, result = handle_peer_commit_sig(peer, msg, inflight_index + 1, + inflight->remote_funding, NULL, inflight->splice_amnt, remote_splice_amnt, @@ -2777,7 +2820,9 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, remote_splice_amnt, next_index_remote - 1, &peer->old_remote_per_commit, - &local_anchor)); + &local_anchor, + 1, + inflight->remote_funding)); } /* Sending and receiving splice commit should not increment commit @@ -2790,14 +2835,15 @@ static struct commitsig *interactive_send_commitments(struct peer *peer, static struct wally_psbt_output *find_channel_output(struct peer *peer, struct wally_psbt *psbt, - u32 *chan_output_index) + u32 *chan_output_index, + const struct pubkey *remote_funding_pubkey) { const u8 *wit_script; u8 *scriptpubkey; wit_script = bitcoin_redeem_2of2(tmpctx, &peer->channel->funding_pubkey[LOCAL], - &peer->channel->funding_pubkey[REMOTE]); + remote_funding_pubkey); scriptpubkey = scriptpubkey_p2wsh(tmpctx, wit_script); @@ -2894,6 +2940,60 @@ relative_splice_balance_fundee(struct peer *peer, return amount_msat(push_value); } +static struct amount_sat calc_balance(struct peer *peer) +{ + struct amount_sat funding_amount_res; + struct amount_msat funding_amount; + struct amount_msat pending_htlcs; + struct htlc_map_iter it; + const struct htlc *htlc; + + /* pending_htlcs holds the value of all pending htlcs for each side */ + pending_htlcs = AMOUNT_MSAT(0); + for (htlc = htlc_map_first(peer->channel->htlcs, &it); + htlc; + htlc = htlc_map_next(peer->channel->htlcs, &it)) { + if (!amount_msat_accumulate(&pending_htlcs, htlc->amount)) + peer_failed_warn(peer->pps, &peer->channel_id, + "Unable to add HTLC balance"); + } + + /* Calculate original channel output amount */ + if (!amount_msat_add(&funding_amount, + peer->channel->view->owed[LOCAL], + peer->channel->view->owed[REMOTE])) + peer_failed_warn(peer->pps, &peer->channel_id, + "Unable to calculate starting channel amount"); + if (!amount_msat_accumulate(&funding_amount, + pending_htlcs)) + peer_failed_warn(peer->pps, &peer->channel_id, + "Unable to calculate starting channel amount"); + + if (!amount_msat_add_sat_s64(&funding_amount, funding_amount, + peer->splicing->opener_relative)) + peer_failed_warn(peer->pps, &peer->channel_id, + "Unable to add opener funding"); + + if (!amount_msat_add_sat_s64(&funding_amount, funding_amount, + peer->splicing->accepter_relative)) + peer_failed_warn(peer->pps, &peer->channel_id, + "Unable to add accepter funding"); + + if (!amount_msat_to_sat(&funding_amount_res, funding_amount)) { + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "splice error: msat of total funding %s should" + " always add up to a full sat. original local bal" + " %s, original remote bal %s,", + fmt_amount_msat(tmpctx, funding_amount), + fmt_amount_msat(tmpctx, + peer->channel->view->owed[LOCAL]), + fmt_amount_msat(tmpctx, + peer->channel->view->owed[REMOTE])); + } + + return funding_amount_res; +} + /* Returns the total channel funding output amount if all checks pass. * Otherwise, exits via peer_failed_warn. DTODO: Change to `tx_abort`. */ static struct amount_sat check_balances(struct peer *peer, @@ -3202,8 +3302,6 @@ static void resume_splice_negotiation(struct peer *peer, struct wally_psbt *current_psbt = inflight->psbt; struct commitsig *their_commit; const struct witness **outws; - u8 der[73]; - size_t der_len; struct bitcoin_signature splice_sig; struct bitcoin_tx *bitcoin_tx; u32 splice_funding_index; @@ -3239,7 +3337,8 @@ static void resume_splice_negotiation(struct peer *peer, &peer->channel->funding_pubkey[LOCAL], &peer->channel->funding_pubkey[REMOTE]); - find_channel_output(peer, current_psbt, &chan_output_index); + find_channel_output(peer, current_psbt, &chan_output_index, + &peer->channel->funding_pubkey[REMOTE]); splice_funding_index = find_channel_funding_input(current_psbt, &peer->channel->funding); @@ -3315,9 +3414,7 @@ static void resume_splice_negotiation(struct peer *peer, fmt_wally_psbt(tmpctx, current_psbt)); txsig_tlvs = tlv_txsigs_tlvs_new(tmpctx); - der_len = signature_to_der(der, &splice_sig); - txsig_tlvs->funding_outpoint_sig = tal_dup_arr(tmpctx, u8, der, - der_len, 0); + txsig_tlvs->shared_input_signature = &splice_sig.s; /* DTODO: is this finalize call required? */ psbt_finalize(current_psbt); @@ -3387,9 +3484,15 @@ static void resume_splice_negotiation(struct peer *peer, &inws), &their_txsigs_tlvs)) peer_failed_warn(peer->pps, &peer->channel_id, - "Splicing bad tx_signatures %s", + "Splicing bad tx_signatures msg %s", tal_hex(msg, msg)); + if (!their_txsigs_tlvs->shared_input_signature) + peer_failed_warn(peer->pps, &peer->channel_id, + "tx_signatures msg must include" + " `shared_input_signature`. Msg: %s", + tal_hex(msg, msg)); + if (peer->splicing) peer->splicing->inws = tal_steal(peer->splicing, inws); @@ -3407,20 +3510,7 @@ static void resume_splice_negotiation(struct peer *peer, * Both nodes: * - MUST sign the transaction using SIGHASH_ALL */ their_sig->sighash_type = SIGHASH_ALL; - - if (!signature_from_der(their_txsigs_tlvs->funding_outpoint_sig, - tal_count(their_txsigs_tlvs->funding_outpoint_sig), - their_sig)) { - - tal_free(their_txsigs_tlvs); - peer_failed_warn(peer->pps, &peer->channel_id, - "Splicing bad tx_signatures %s", - tal_hex(msg, msg)); - } - if (peer->splicing) - peer->splicing->their_sig = tal_steal(peer->splicing, - their_sig); - tal_free(their_txsigs_tlvs); + their_sig->s = *their_txsigs_tlvs->shared_input_signature; /* Set the commit_sig on the commitment tx psbt */ if (!psbt_input_set_signature(current_psbt, @@ -3582,6 +3672,23 @@ static void update_hsmd_with_splice(struct peer *peer, struct inflight *inflight tal_hex(tmpctx, msg)); } +static struct bitcoin_tx *bitcoin_tx_from_txid(struct peer *peer, + struct bitcoin_txid txid) +{ + u8 *msg; + struct bitcoin_tx *tx = NULL; + + msg = towire_channeld_splice_lookup_tx(NULL, &txid); + + msg = master_wait_sync_reply(tmpctx, peer, take(msg), + WIRE_CHANNELD_SPLICE_LOOKUP_TX_RESULT); + + if (!fromwire_channeld_splice_lookup_tx_result(tmpctx, msg, &tx)) + master_badmsg(WIRE_CHANNELD_SPLICE_LOOKUP_TX_RESULT, msg); + + return tx; +} + /* ACCEPTER side of the splice. Here we handle all the accepter's steps for the * splice. Since the channel must be in STFU mode we block the daemon here until * the splice is finished or aborted. */ @@ -3590,12 +3697,10 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) const u8 *msg; struct interactivetx_context *ictx; u32 splice_funding_index; - struct bitcoin_blkid genesis_blockhash; struct channel_id channel_id; struct amount_sat both_amount; u32 funding_feerate_perkw; u32 locktime; - struct pubkey splice_remote_pubkey; char *error; struct inflight *new_inflight; struct wally_psbt_output *new_chan_output; @@ -3613,11 +3718,10 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) if (!fromwire_splice(inmsg, &channel_id, - &genesis_blockhash, &peer->splicing->opener_relative, &funding_feerate_perkw, &locktime, - &splice_remote_pubkey)) + &peer->splicing->remote_funding_pubkey)) peer_failed_warn(peer->pps, &peer->channel_id, "Bad wire_splice %s", tal_hex(tmpctx, inmsg)); @@ -3627,19 +3731,13 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) peer_failed_warn(peer->pps, &peer->channel_id, "Must be in STFU mode before intiating splice"); - if (!bitcoin_blkid_eq(&genesis_blockhash, - &chainparams->genesis_blockhash)) - peer_failed_warn(peer->pps, &peer->channel_id, - "Bad splice blockhash"); - if (!channel_id_eq(&channel_id, &peer->channel_id)) peer_failed_warn(peer->pps, &peer->channel_id, "Splice internal error: mismatched channelid"); - if (!pubkey_eq(&splice_remote_pubkey, + if (!pubkey_eq(&peer->splicing->remote_funding_pubkey, &peer->channel->funding_pubkey[REMOTE])) - peer_failed_warn(peer->pps, &peer->channel_id, - "Splice doesnt support changing pubkeys"); + status_info("Splice peer is rotating funding pubkey"); if (funding_feerate_perkw < peer->feerate_min) peer_failed_warn(peer->pps, &peer->channel_id, @@ -3650,7 +3748,6 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) msg = towire_splice_ack(NULL, &peer->channel_id, - &chainparams->genesis_blockhash, peer->splicing->accepter_relative, &peer->channel->funding_pubkey[LOCAL]); @@ -3668,6 +3765,11 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) ictx->desired_psbt = NULL; ictx->pause_when_complete = false; + ictx->shared_outpoint = tal(ictx, struct bitcoin_outpoint); + *ictx->shared_outpoint = peer->channel->funding; + ictx->funding_tx = bitcoin_tx_from_txid(peer, + peer->channel->funding.txid); + error = process_interactivetx_updates(tmpctx, ictx, &peer->splicing->received_tx_complete, &abort_msg); @@ -3687,7 +3789,8 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) &peer->channel->funding); new_chan_output = find_channel_output(peer, ictx->current_psbt, - &outpoint.n); + &outpoint.n, + &peer->splicing->remote_funding_pubkey); both_amount = check_balances(peer, our_role, ictx->current_psbt, outpoint.n, splice_funding_index); @@ -3703,6 +3806,7 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) fmt_wally_psbt(tmpctx, ictx->current_psbt)); msg = towire_channeld_add_inflight(NULL, + &peer->splicing->remote_funding_pubkey, &outpoint.txid, outpoint.n, funding_feerate_perkw, @@ -3719,6 +3823,7 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) psbt_txid(new_inflight, ictx->current_psbt, &new_inflight->outpoint.txid, NULL); + new_inflight->remote_funding = peer->splicing->remote_funding_pubkey; new_inflight->outpoint = outpoint; new_inflight->amnt = both_amount; new_inflight->psbt = tal_steal(new_inflight, ictx->current_psbt); @@ -3738,64 +3843,39 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) resume_splice_negotiation(peer, true, true, true, true); } -static struct bitcoin_tx *bitcoin_tx_from_txid(struct peer *peer, - struct bitcoin_txid txid) -{ - u8 *msg; - struct bitcoin_tx *tx = NULL; - - msg = towire_channeld_splice_lookup_tx(NULL, &txid); - - msg = master_wait_sync_reply(tmpctx, peer, take(msg), - WIRE_CHANNELD_SPLICE_LOOKUP_TX_RESULT); - - if (!fromwire_channeld_splice_lookup_tx_result(tmpctx, msg, &tx)) - master_badmsg(WIRE_CHANNELD_SPLICE_LOOKUP_TX_RESULT, msg); - - return tx; -} - /* splice_initiator runs when splice_ack is received by the other side. It * handles the initial splice creation while callbacks will handle later * stages. */ static void splice_initiator(struct peer *peer, const u8 *inmsg) { - struct bitcoin_blkid genesis_blockhash; struct channel_id channel_id; - struct pubkey splice_remote_pubkey; size_t input_index; - const u8 *wit_script; + const u8 *wit_script, *new_wit_script; u8 *outmsg; struct interactivetx_context *ictx; struct bitcoin_tx *prev_tx; u32 sequence = 0; u8 *scriptPubkey; + /* DTODO: Remove ictx from this function as its no longer used. */ ictx = new_interactivetx_context(tmpctx, TX_INITIATOR, peer->pps, peer->channel_id); if (!fromwire_splice_ack(inmsg, &channel_id, - &genesis_blockhash, &peer->splicing->accepter_relative, - &splice_remote_pubkey)) + &peer->splicing->remote_funding_pubkey)) peer_failed_warn(peer->pps, &peer->channel_id, "Bad wire_splice_ack %s", tal_hex(tmpctx, inmsg)); - if (!bitcoin_blkid_eq(&genesis_blockhash, - &chainparams->genesis_blockhash)) - peer_failed_warn(peer->pps, &peer->channel_id, - "Bad splice[ACK] blockhash"); - if (!channel_id_eq(&channel_id, &peer->channel_id)) peer_failed_warn(peer->pps, &peer->channel_id, "Splice[ACK] internal error: mismatched channelid"); - if (!pubkey_eq(&splice_remote_pubkey, + if (!pubkey_eq(&peer->splicing->remote_funding_pubkey, &peer->channel->funding_pubkey[REMOTE])) - peer_failed_warn(peer->pps, &peer->channel_id, - "Splice[ACK] doesnt support changing pubkeys"); + status_info("Splice[ACK] peer is rotating funding pubkey"); peer->splicing->received_tx_complete = false; peer->splicing->sent_tx_complete = false; @@ -3816,6 +3896,9 @@ static void splice_initiator(struct peer *peer, const u8 *inmsg) wit_script = bitcoin_redeem_2of2(tmpctx, &peer->channel->funding_pubkey[LOCAL], &peer->channel->funding_pubkey[REMOTE]); + new_wit_script = bitcoin_redeem_2of2(tmpctx, + &peer->channel->funding_pubkey[LOCAL], + &peer->splicing->remote_funding_pubkey); input_index = ictx->desired_psbt->num_inputs; @@ -3853,11 +3936,15 @@ static void splice_initiator(struct peer *peer, const u8 *inmsg) * funding keys using the higher of the two `generation` fields. */ psbt_append_output(ictx->desired_psbt, - scriptpubkey_p2wsh(ictx->desired_psbt, wit_script), - amount_sat(0)); + scriptpubkey_p2wsh(ictx->desired_psbt, new_wit_script), + calc_balance(peer)); psbt_add_serials(ictx->desired_psbt, ictx->our_role); + ictx->shared_outpoint = tal(ictx, struct bitcoin_outpoint); + *ictx->shared_outpoint = peer->channel->funding; + ictx->funding_tx = prev_tx; + peer->splicing->tx_add_input_count = 0; peer->splicing->tx_add_output_count = 0; @@ -3881,6 +3968,7 @@ static void splice_initiator_user_finalized(struct peer *peer) { u8 *outmsg; struct interactivetx_context *ictx; + struct bitcoin_tx *prev_tx; bool sign_first; char *error; u32 chan_output_index, splice_funding_index; @@ -3893,6 +3981,9 @@ static void splice_initiator_user_finalized(struct peer *peer) const enum tx_role our_role = TX_INITIATOR; u8 *abort_msg; + /* We must loading the funding tx as our previous utxo */ + prev_tx = bitcoin_tx_from_txid(peer, peer->channel->funding.txid); + ictx = new_interactivetx_context(tmpctx, our_role, peer->pps, peer->channel_id); @@ -3902,6 +3993,10 @@ static void splice_initiator_user_finalized(struct peer *peer) ictx->tx_add_input_count = peer->splicing->tx_add_input_count; ictx->tx_add_output_count = peer->splicing->tx_add_output_count; + ictx->shared_outpoint = tal(ictx, struct bitcoin_outpoint); + *ictx->shared_outpoint = peer->channel->funding; + ictx->funding_tx = prev_tx; + error = process_interactivetx_updates(tmpctx, ictx, &peer->splicing->received_tx_complete, &abort_msg); @@ -3918,7 +4013,8 @@ static void splice_initiator_user_finalized(struct peer *peer) psbt_sort_by_serial_id(ictx->current_psbt); new_chan_output = find_channel_output(peer, ictx->current_psbt, - &chan_output_index); + &chan_output_index, + &peer->splicing->remote_funding_pubkey); splice_funding_index = find_channel_funding_input(ictx->current_psbt, &peer->channel->funding); @@ -3935,6 +4031,7 @@ static void splice_initiator_user_finalized(struct peer *peer) psbt_txid(tmpctx, ictx->current_psbt, ¤t_psbt_txid, NULL); outmsg = towire_channeld_add_inflight(tmpctx, + &peer->splicing->remote_funding_pubkey, ¤t_psbt_txid, chan_output_index, peer->splicing->feerate_per_kw, @@ -3951,6 +4048,7 @@ static void splice_initiator_user_finalized(struct peer *peer) psbt_txid(tmpctx, ictx->current_psbt, &new_inflight->outpoint.txid, NULL); + new_inflight->remote_funding = peer->splicing->remote_funding_pubkey; new_inflight->outpoint.n = chan_output_index; new_inflight->amnt = amount_sat(new_chan_output->amount); new_inflight->splice_amnt = peer->splicing->opener_relative; @@ -4161,7 +4259,6 @@ static void handle_splice_stfu_success(struct peer *peer) { u8 *msg = towire_splice(tmpctx, &peer->channel_id, - &chainparams->genesis_blockhash, peer->splicing->opener_relative, peer->splicing->feerate_per_kw, peer->splicing->current_psbt->fallback_locktime, @@ -4296,7 +4393,16 @@ static void handle_stfu_req(struct peer *peer, const u8 *inmsg) peer->stfu_initiator = LOCAL; peer->want_stfu = true; - maybe_send_stfu(peer); + + if (!maybe_send_stfu(peer)) { + msg = towire_channeld_splice_state_error(NULL, tal_fmt(tmpctx, + "Pending updates" + " prevent us from STFU" + " mode at this" + " time.")); + wire_sync_write(MASTER_FD, take(msg)); + return; + } } static void handle_abort_req(struct peer *peer, const u8 *inmsg) @@ -4370,8 +4476,9 @@ static void peer_in(struct peer *peer, const u8 *msg) handle_peer_add_htlc(peer, msg); return; case WIRE_COMMITMENT_SIGNED: - handle_peer_commit_sig(peer, msg, 0, NULL, 0, 0, - peer->next_index[LOCAL], + handle_peer_commit_sig(peer, msg, 0, + peer->channel->funding_pubkey[REMOTE], + NULL, 0, 0, peer->next_index[LOCAL], &peer->next_local_per_commit, false); return; case WIRE_UPDATE_FEE: @@ -4511,6 +4618,7 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last) u8 *msg; u8 **msgs = tal_arr(tmpctx, u8*, 1); struct local_anchor_info *local_anchor; + u16 batch_size = tal_count(peer->splice_state->inflights) + 1; status_debug("Retransmitting commitment, feerate LOCAL=%u REMOTE=%u," " blockheight LOCAL=%u REMOTE=%u", @@ -4605,7 +4713,8 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last) peer->channel->funding_sats, NULL, false, 0, 0, peer->next_index[REMOTE] - 1, &peer->remote_per_commit, - &local_anchor); + &local_anchor, batch_size, + peer->channel->funding_pubkey[REMOTE]); /* Loop over current inflights * BOLT-0d8b701614b09c6ee4172b04da2203e73deec7e2 #2: @@ -4631,7 +4740,8 @@ static void resend_commitment(struct peer *peer, struct changed_htlc *last) remote_splice_amnt, peer->next_index[REMOTE] - 1, &peer->remote_per_commit, - &local_anchor)); + &local_anchor, batch_size, + peer->splice_state->inflights[i]->remote_funding)); } for(i = 0; i < tal_count(msgs); i++) diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index 592a8b65a6b9..e9139ef435c0 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -255,6 +255,7 @@ msgdata,channeld_splice_feerate_error,too_high,bool, # channeld->master: Add an inflight to the DB msgtype,channeld_add_inflight,7216 +msgdata,channeld_add_inflight,remote_funding,pubkey, msgdata,channeld_add_inflight,tx_id,bitcoin_txid, msgdata,channeld_add_inflight,tx_outnum,u32, msgdata,channeld_add_inflight,feerate,u32, @@ -287,7 +288,7 @@ msgdata,channeld_splice_state_error,state_error,wirestring, 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, +msgdata,channeld_splice_abort,reason,wirestring, # master->channeld: Please enter stfu mode msgtype,channeld_stfu,7224 diff --git a/channeld/full_channel.c b/channeld/full_channel.c index 9cea6656792e..79c0b2da3ce5 100644 --- a/channeld/full_channel.c +++ b/channeld/full_channel.c @@ -309,13 +309,17 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, enum side side, s64 splice_amnt, s64 remote_splice_amnt, - int *other_anchor_outnum) + int *other_anchor_outnum, + const struct pubkey funding_pubkeys[NUM_SIDES]) { struct bitcoin_tx **txs; const struct htlc **committed; struct keyset keyset; struct amount_msat side_pay, other_side_pay; + if (!funding_pubkeys) + funding_pubkeys = channel->funding_pubkey; + if (!derive_keyset(per_commitment_point, &channel->basepoints[side], &channel->basepoints[!side], @@ -329,8 +333,8 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, /* Generating and saving witness script required to spend * the funding output */ *funding_wscript = bitcoin_redeem_2of2(ctx, - &channel->funding_pubkey[side], - &channel->funding_pubkey[!side]); + &funding_pubkeys[side], + &funding_pubkeys[!side]); side_pay = channel->view[side].owed[side]; other_side_pay = channel->view[side].owed[!side]; @@ -351,8 +355,8 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, txs[0] = commit_tx( txs, funding, funding_sats, - &channel->funding_pubkey[side], - &channel->funding_pubkey[!side], + &funding_pubkeys[side], + &funding_pubkeys[!side], channel->opener, channel->config[!side].to_self_delay, channel->lease_expiry, @@ -367,9 +371,9 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, /* Set the remote/local pubkeys on the commitment tx psbt */ psbt_input_add_pubkey(txs[0]->psbt, 0, - &channel->funding_pubkey[side], false /* is_taproot */); + &funding_pubkeys[side], false /* is_taproot */); psbt_input_add_pubkey(txs[0]->psbt, 0, - &channel->funding_pubkey[!side], false /* is_taproot */); + &funding_pubkeys[!side], false /* is_taproot */); add_htlcs(&txs, *htlcmap, channel, &keyset, side); diff --git a/channeld/full_channel.h b/channeld/full_channel.h index 05ebf8da0364..3eaba5086c07 100644 --- a/channeld/full_channel.h +++ b/channeld/full_channel.h @@ -67,6 +67,7 @@ struct channel *new_full_channel(const tal_t *ctx, * @local_splice_amnt: how much is being spliced in (or out, if -ve) of local side. * @remote_splice_amnt: how much is being spliced in (or out, if -ve) of remote side. * @other_anchor_outnum: which output (-1 if none) is the !!side anchor + * @funding_pubkeys: The funding pubkeys (specify NULL to use channel's value). * * Returns the unsigned commitment transaction for the committed state * for @side, followed by the htlc transactions in output order and @@ -84,7 +85,8 @@ struct bitcoin_tx **channel_txs(const tal_t *ctx, enum side side, s64 local_splice_amnt, s64 remote_splice_amnt, - int *local_anchor_outnum); + int *local_anchor_outnum, + const struct pubkey funding_pubkeys[NUM_SIDES]); /** * actual_feerate: what is the actual feerate for the local side. diff --git a/channeld/inflight.c b/channeld/inflight.c index a1e908ead6ab..d06142bf324d 100644 --- a/channeld/inflight.c +++ b/channeld/inflight.c @@ -9,6 +9,7 @@ struct inflight *fromwire_inflight(const tal_t *ctx, const u8 **cursor, size_t * struct inflight *inflight = tal(ctx, struct inflight); fromwire_bitcoin_outpoint(cursor, max, &inflight->outpoint); + fromwire_pubkey(cursor, max, &inflight->remote_funding); inflight->amnt = fromwire_amount_sat(cursor, max); inflight->remote_tx_sigs = fromwire_bool(cursor, max); inflight->psbt = fromwire_wally_psbt(inflight, cursor, max); @@ -31,6 +32,7 @@ struct inflight *fromwire_inflight(const tal_t *ctx, const u8 **cursor, size_t * void towire_inflight(u8 **pptr, const struct inflight *inflight) { towire_bitcoin_outpoint(pptr, &inflight->outpoint); + towire_pubkey(pptr, &inflight->remote_funding); towire_amount_sat(pptr, inflight->amnt); towire_bool(pptr, inflight->remote_tx_sigs); towire_wally_psbt(pptr, inflight->psbt); @@ -43,16 +45,3 @@ void towire_inflight(u8 **pptr, const struct inflight *inflight) towire_bool(pptr, inflight->i_am_initiator); towire_bool(pptr, inflight->force_sign_first); } - -void copy_inflight(struct inflight *dest, struct inflight *src) -{ - dest->outpoint = src->outpoint; - dest->amnt = src->amnt; - dest->remote_tx_sigs = src->remote_tx_sigs; - dest->psbt = src->psbt ? clone_psbt(dest, src->psbt): NULL; - dest->splice_amnt = src->splice_amnt; - dest->last_tx = src->last_tx ? clone_bitcoin_tx(dest, src->last_tx) : NULL; - dest->last_sig = src->last_sig; - dest->i_am_initiator = src->i_am_initiator; - dest->force_sign_first = src->force_sign_first; -} diff --git a/channeld/inflight.h b/channeld/inflight.h index 47deb316681d..2c296f43148e 100644 --- a/channeld/inflight.h +++ b/channeld/inflight.h @@ -2,11 +2,13 @@ #define LIGHTNING_CHANNELD_INFLIGHT_H #include "config.h" +#include #include #include struct inflight { struct bitcoin_outpoint outpoint; + struct pubkey remote_funding; struct amount_sat amnt; bool remote_tx_sigs; struct wally_psbt *psbt; @@ -22,6 +24,4 @@ struct inflight { struct inflight *fromwire_inflight(const tal_t *ctx, const u8 **cursor, size_t *max); void towire_inflight(u8 **pptr, const struct inflight *inflight); -void copy_inflight(struct inflight *dest, struct inflight *src); - #endif /* LIGHTNING_CHANNELD_INFLIGHT_H */ diff --git a/channeld/splice.h b/channeld/splice.h index eca46eb5c6c5..92bea28284e4 100644 --- a/channeld/splice.h +++ b/channeld/splice.h @@ -31,6 +31,8 @@ struct splice_state *splice_state_new(const tal_t *ctx); /* An active splice negotiation. Born when splice beings and dies when a splice * negotation has finished */ struct splicing { + /* The remote side's rotated funding pubkey */ + struct pubkey remote_funding_pubkey; /* The opener side's relative balance change */ s64 opener_relative; /* The accepter side's relative balance change */ diff --git a/channeld/test/run-full_channel.c b/channeld/test/run-full_channel.c index 95757e8de974..c0d41ab79a04 100644 --- a/channeld/test/run-full_channel.c +++ b/channeld/test/run-full_channel.c @@ -555,7 +555,7 @@ int main(int argc, const char *argv[]) txs = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript_alt, lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, - &local_anchor); + &local_anchor, NULL); assert(tal_count(txs) == 1); assert(tal_count(htlc_map) == 2); assert(scripteq(funding_wscript_alt, funding_wscript)); @@ -564,7 +564,7 @@ int main(int argc, const char *argv[]) txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, - &local_anchor); + &local_anchor, NULL); txs_must_be_eq(txs, txs2); /* BOLT #3: @@ -593,12 +593,12 @@ int main(int argc, const char *argv[]) txs = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, - &local_anchor); + &local_anchor, NULL); assert(tal_count(txs) == 1); txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, - &local_anchor); + &local_anchor, NULL); txs_must_be_eq(txs, txs2); update_feerate(lchannel, feerate_per_kw[LOCAL]); @@ -615,12 +615,12 @@ int main(int argc, const char *argv[]) txs = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, - &local_anchor); + &local_anchor, NULL); assert(tal_count(txs) == 6); txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, - &local_anchor); + &local_anchor, NULL); txs_must_be_eq(txs, txs2); /* FIXME: Compare signatures! */ @@ -695,14 +695,14 @@ int main(int argc, const char *argv[]) &htlc_map, NULL, &funding_wscript, lchannel, &local_per_commitment_point, 42, LOCAL, 0, 0, - &local_anchor); + &local_anchor, NULL); tx_must_be_eq(txs[0], raw_tx); txs2 = channel_txs(tmpctx, &funding, funding_amount, &htlc_map, NULL, &funding_wscript, rchannel, &local_per_commitment_point, 42, REMOTE, 0, 0, - &local_anchor); + &local_anchor, NULL); txs_must_be_eq(txs, txs2); } diff --git a/common/interactivetx.c b/common/interactivetx.c index 9fa09d84fbc1..a9163a7dcf1c 100644 --- a/common/interactivetx.c +++ b/common/interactivetx.c @@ -64,6 +64,8 @@ struct interactivetx_context *new_interactivetx_context(const tal_t *ctx, ictx->our_role = our_role; ictx->pps = pps; ictx->channel_id = channel_id; + ictx->shared_outpoint = NULL; + ictx->funding_tx = NULL; ictx->tx_add_input_count = 0; ictx->tx_add_output_count = 0; ictx->next_update_fn = default_next_update; @@ -208,6 +210,7 @@ static char *send_next(const tal_t *ctx, if (tal_count(set->added_ins) != 0) { const struct input_set *in = &set->added_ins[0]; + struct bitcoin_outpoint point; u8 *prevtx; if (!psbt_get_serial_id(&in->input.unknowns, &serial_id)) @@ -220,9 +223,24 @@ static char *send_next(const tal_t *ctx, return "interactivetx ADD_INPUT PSBT needs the previous" " transaction set."; - msg = towire_tx_add_input(NULL, cid, serial_id, - prevtx, in->input.index, - in->input.sequence); + wally_psbt_input_get_outpoint(&in->input, &point); + + /* If this the shared channel input, we send funding txid in + * in tlvs and do not send prevtx */ + if (ictx->shared_outpoint + && bitcoin_outpoint_eq(&point, ictx->shared_outpoint)) { + struct tlv_tx_add_input_tlvs *tlvs = tal(tmpctx, struct tlv_tx_add_input_tlvs); + tlvs->shared_input_txid = tal_dup(tlvs, + struct bitcoin_txid, + &point.txid); + msg = towire_tx_add_input(NULL, cid, serial_id, + NULL, in->input.index, + in->input.sequence, tlvs); + } else { + msg = towire_tx_add_input(NULL, cid, serial_id, + prevtx, in->input.index, + in->input.sequence, NULL); + } tal_arr_remove(&set->added_ins, 0); } @@ -417,12 +435,14 @@ char *process_interactivetx_updates(const tal_t *ctx, size_t len; struct bitcoin_tx *tx; struct bitcoin_outpoint outpoint; + struct tlv_tx_add_input_tlvs *tlvs; if (!fromwire_tx_add_input(ctx, msg, &cid, &serial_id, cast_const2(u8 **, &tx_bytes), - &outpoint.n, &sequence)) + &outpoint.n, &sequence, + &tlvs)) return tal_fmt(ctx, "Parsing tx_add_input %s", tal_hex(ctx, msg)); @@ -459,13 +479,30 @@ char *process_interactivetx_updates(const tal_t *ctx, return tal_fmt(ctx, "Duplicate serial_id rcvd" " %"PRIu64, serial_id); - /* Convert tx_bytes to a tx! */ - len = tal_bytelen(tx_bytes); - tx = pull_bitcoin_tx_only(ctx, &tx_bytes, &len); - - if (!tx || len != 0) - return tal_fmt(ctx, "Invalid tx sent. len: %d", - (int)len); + /* For our shared input only, we will fill in prevtx */ + if (ictx->shared_outpoint && tlvs->shared_input_txid) { + if (!bitcoin_txid_eq(tlvs->shared_input_txid, + &ictx->shared_outpoint->txid)) + return tal_fmt(ctx, "funding_txid value" + " %s unrecognized." + " Should be %s", + fmt_bitcoin_txid(ctx, tlvs->shared_input_txid), + fmt_bitcoin_txid(ctx, &ictx->shared_outpoint->txid)); + if (!ictx->funding_tx) + return tal_fmt(ctx, "Internal error" + " did not set" + " interactivetx" + " funding_tx"); + tx = ictx->funding_tx; + } + else { + /* Convert tx_bytes to a tx! */ + len = tal_bytelen(tx_bytes); + tx = pull_bitcoin_tx_only(ctx, &tx_bytes, &len); + if (!tx || len != 0) + return tal_fmt(ctx, "Invalid tx sent. len: %d", + (int)len); + } if (outpoint.n >= tx->wtx->num_outputs) return tal_fmt(ctx, diff --git a/common/interactivetx.h b/common/interactivetx.h index d2233f4df463..af17e1453c8e 100644 --- a/common/interactivetx.h +++ b/common/interactivetx.h @@ -30,6 +30,14 @@ struct interactivetx_context { struct per_peer_state *pps; struct channel_id channel_id; + /* The existing funding outpoint of a channel being spliced. + * This input will send funding_txid instead of prevtx. */ + struct bitcoin_outpoint *shared_outpoint; + + /* When receiving `tx_add_input` we will fill in prevtx using this + * value when `shared_outpoint`'s txid matches */ + struct bitcoin_tx *funding_tx; + /* Track how many of each tx collab msg we receive */ u16 tx_add_input_count, tx_add_output_count; diff --git a/common/jsonrpc_errors.h b/common/jsonrpc_errors.h index 000ae8b3a531..da9e337720e1 100644 --- a/common/jsonrpc_errors.h +++ b/common/jsonrpc_errors.h @@ -84,6 +84,7 @@ enum jsonrpc_errcode { SPLICE_LOW_FEE = 359, SPLICE_HIGH_FEE = 360, SPLICE_ABORT = 362, + SPLICE_CHANNEL_ERROR = 363, /* `connect` errors */ CONNECT_NO_KNOWN_ADDRESS = 400, diff --git a/common/wire_error.c b/common/wire_error.c index 97e121ee798f..512a1cf6b78a 100644 --- a/common/wire_error.c +++ b/common/wire_error.c @@ -72,6 +72,43 @@ u8 *towire_warningfmt(const tal_t *ctx, return msg; } +u8 *towire_abortfmtv(const tal_t *ctx, + const struct channel_id *channel, + const char *fmt, + va_list ap) +{ + /* BOLT #1: + * + * The channel is referred to by `channel_id`, unless `channel_id` is + * 0 (i.e. all bytes are 0), in which case it refers to all + * channels. */ + static const struct channel_id all_channels; + char *estr; + u8 *msg; + + estr = tal_vfmt(ctx, fmt, ap); + /* We need tal_len to work, so we use copy. */ + msg = towire_tx_abort(ctx, channel ? channel : &all_channels, + (u8 *)tal_dup_arr(estr, char, estr, strlen(estr), 0)); + tal_free(estr); + + return msg; +} + +u8 *towire_abortfmt(const tal_t *ctx, + const struct channel_id *channel, + const char *fmt, ...) +{ + va_list ap; + u8 *msg; + + va_start(ap, fmt); + msg = towire_abortfmtv(ctx, channel, fmt, ap); + va_end(ap); + + return msg; +} + bool channel_id_is_all(const struct channel_id *channel_id) { return memeqzero(channel_id, sizeof(*channel_id)); diff --git a/common/wire_error.h b/common/wire_error.h index 7797295bb878..6fe932513801 100644 --- a/common/wire_error.h +++ b/common/wire_error.h @@ -54,6 +54,30 @@ u8 *towire_warningfmtv(const tal_t *ctx, const char *fmt, va_list ap); +/** + * towire_abortfmt - helper to turn string into WIRE_TX_ABORT. + * + * @ctx: context to allocate from + * @channel: specific channel to complain about, or NULL for all. + * @fmt: format for warning. + */ +u8 *towire_abortfmt(const tal_t *ctx, + const struct channel_id *channel, + const char *fmt, ...) PRINTF_FMT(3,4); + +/** + * towire_abortfmtv - helper to turn string into WIRE_TX_ABORT. + * + * @ctx: context to allocate from + * @channel: specific channel to complain about, or NULL for all. + * @fmt: format for warning. + * @ap: accumulated varargs. + */ +u8 *towire_abortfmtv(const tal_t *ctx, + const struct channel_id *channel, + const char *fmt, + va_list ap); + /* BOLT #1: * * The channel is referred to by `channel_id`, unless `channel_id` is 0 diff --git a/devtools/mkcommit.c b/devtools/mkcommit.c index 93d3b470db77..069282b2f343 100644 --- a/devtools/mkcommit.c +++ b/devtools/mkcommit.c @@ -425,7 +425,7 @@ int main(int argc, char *argv[]) local_txs = channel_txs(NULL, &channel->funding, channel->funding_sats, &htlcmap, NULL, &funding_wscript, channel, &local_per_commit_point, commitnum, - LOCAL, 0, 0, &local_anchor_outnum); + LOCAL, 0, 0, &local_anchor_outnum, NULL); printf("## local_commitment\n" "# input amount %s, funding_wscript %s, pubkey %s\n", @@ -536,7 +536,7 @@ int main(int argc, char *argv[]) remote_txs = channel_txs(NULL, &channel->funding, channel->funding_sats, &htlcmap, NULL, &funding_wscript, channel, &remote_per_commit_point, commitnum, - REMOTE, 0, 0, &local_anchor_outnum); + REMOTE, 0, 0, &local_anchor_outnum, NULL); printf("## remote_commitment\n" "# input amount %s, funding_wscript %s, key %s\n", diff --git a/lightningd/channel.c b/lightningd/channel.c index 93e4bd35256a..c7201de2fc1a 100644 --- a/lightningd/channel.c +++ b/lightningd/channel.c @@ -152,6 +152,7 @@ static void destroy_inflight(struct channel_inflight *inflight) struct channel_inflight * new_inflight(struct channel *channel, + struct pubkey *remote_funding, const struct bitcoin_outpoint *funding_outpoint, u32 funding_feerate, struct amount_sat total_funds, @@ -177,6 +178,7 @@ new_inflight(struct channel *channel, funding->feerate = funding_feerate; funding->our_funds = our_funds; funding->splice_amnt = splice_amnt; + funding->splice_remote_funding = tal_steal(funding, remote_funding); inflight->funding = funding; inflight->channel = channel; diff --git a/lightningd/channel.h b/lightningd/channel.h index cb74323166e0..7291b507deac 100644 --- a/lightningd/channel.h +++ b/lightningd/channel.h @@ -41,6 +41,7 @@ struct funding_info { /* Relative splicing balance change */ s64 splice_amnt; + struct pubkey *splice_remote_funding; }; struct channel_inflight { @@ -431,6 +432,7 @@ struct channel *new_channel(struct peer *peer, u64 dbid, /* new_inflight - Create a new channel_inflight for a channel */ struct channel_inflight *new_inflight(struct channel *channel, + struct pubkey *remote_funding STEALS, const struct bitcoin_outpoint *funding_outpoint, u32 funding_feerate, struct amount_sat funding_sat, diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index e545714a0112..fc54e537b3f9 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -371,7 +371,7 @@ static void handle_splice_abort(struct lightningd *ld, log_debug(channel->log, "made the socket pair"); if (peer_start_channeld(channel, new_peer_fd(tmpctx, fds[0]), NULL, - true, false)) { + false, false)) { log_info(channel->log, "Sending the peer fd to connectd"); subd_send_msg(ld->connectd, take(towire_connectd_peer_connect_subd(NULL, @@ -824,6 +824,7 @@ static void handle_add_inflight(struct lightningd *ld, struct channel *channel, const u8 *msg) { + struct pubkey *remote_funding = tal(tmpctx, struct pubkey); struct bitcoin_outpoint outpoint; u32 feerate; struct amount_sat satoshis; @@ -834,6 +835,7 @@ static void handle_add_inflight(struct lightningd *ld, if (!fromwire_channeld_add_inflight(tmpctx, msg, + remote_funding, &outpoint.txid, &outpoint.n, &feerate, @@ -849,6 +851,7 @@ static void handle_add_inflight(struct lightningd *ld, } inflight = new_inflight(channel, + remote_funding, &outpoint, feerate, satoshis, @@ -1625,6 +1628,27 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) return 0; } +/* If we get a disconnecting warning or error during a splice command, let + * the user know out of an abundance of politeness. + * After, we forward the event onto the standard `channel_errmsg`. */ +static void channel_control_errmsg(struct channel *channel, + struct peer_fd *peer_fd, + const char *desc, + const u8 *err_for_them, + bool disconnect, + bool warning) +{ + struct lightningd *ld = channel->peer->ld; + struct splice_command *cc = splice_command_for_chan(ld, channel); + if (cc && disconnect) { + was_pending(command_fail(cc->cmd, SPLICE_CHANNEL_ERROR, + "Splice command failed:" + " %s", desc)); + } + + channel_errmsg(channel, peer_fd, desc, err_for_them, disconnect, warning); +} + bool peer_start_channeld(struct channel *channel, struct peer_fd *peer_fd, const u8 *fwd_msg, @@ -1674,7 +1698,7 @@ bool peer_start_channeld(struct channel *channel, channel->log, true, channeld_wire_name, channel_msg, - channel_errmsg, + channel_control_errmsg, channel_set_billboard, take(&peer_fd->fd), take(&hsmfd), NULL)); @@ -1776,6 +1800,7 @@ bool peer_start_channeld(struct channel *channel, infcopy = tal(inflights, struct inflight); + infcopy->remote_funding = *inflight->funding->splice_remote_funding; infcopy->outpoint = inflight->funding->outpoint; infcopy->amnt = inflight->funding->total_funds; infcopy->remote_tx_sigs = inflight->remote_tx_sigs; @@ -2139,9 +2164,9 @@ static struct command_result *channel_for_splice(struct command *cmd, if (!feature_negotiated(cmd->ld->our_features, (*channel)->peer->their_features, - OPT_EXPERIMENTAL_SPLICE)) + OPT_SPLICE)) return command_fail(cmd, SPLICE_NOT_SUPPORTED, - "splicing not supported"); + "Peer does not support splicing"); if (!(*channel)->owner) return command_fail(cmd, SPLICE_WRONG_OWNER, diff --git a/lightningd/dual_open_control.c b/lightningd/dual_open_control.c index 129d14209f5e..741710a39417 100644 --- a/lightningd/dual_open_control.c +++ b/lightningd/dual_open_control.c @@ -1283,6 +1283,7 @@ wallet_update_channel(struct lightningd *ld, /* Add open attempt to channel's inflights */ inflight = new_inflight(channel, + NULL, &channel->funding, funding_feerate, channel->funding_sats, @@ -1502,6 +1503,7 @@ wallet_commit_channel(struct lightningd *ld, /* Open attempt to channel's inflights */ inflight = new_inflight(channel, + NULL, &channel->funding, funding_feerate, channel->funding_sats, diff --git a/lightningd/hsm_control.c b/lightningd/hsm_control.c index 98ab7a316d0d..d4c0ccfb2274 100644 --- a/lightningd/hsm_control.c +++ b/lightningd/hsm_control.c @@ -177,7 +177,7 @@ struct ext_key *hsm_init(struct lightningd *ld) } if (feature_offered(ld->our_features->bits[INIT_FEATURE], - OPT_EXPERIMENTAL_SPLICE) + OPT_SPLICE) && !hsm_capable(ld, WIRE_HSMD_SIGN_SPLICE_TX)) { fatal("--experimental-splicing needs HSM capable of signing splices!"); } diff --git a/lightningd/options.c b/lightningd/options.c index 379b89ac33dc..43d32700ac34 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -1263,7 +1263,7 @@ static char *opt_set_splicing(struct lightningd *ld) { feature_set_or(ld->our_features, take(feature_set_for_feature(NULL, - OPTIONAL_FEATURE(OPT_EXPERIMENTAL_SPLICE)))); + OPTIONAL_FEATURE(OPT_SPLICE)))); return NULL; } @@ -2058,7 +2058,7 @@ void add_config_deprecated(struct lightningd *ld, json_add_bool(response, name0, feature_offered(ld->our_features ->bits[INIT_FEATURE], - OPT_EXPERIMENTAL_SPLICE)); + OPT_SPLICE)); } else if (opt->cb == (void *)opt_set_onion_messages) { json_add_bool(response, name0, feature_offered(ld->our_features diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 0f031a6199a4..90127ffdfcba 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2058,6 +2058,10 @@ void update_channel_from_inflight(struct lightningd *ld, bitcoin_tx_with_psbt(channel, psbt_copy), &inflight->last_sig); + /* If the remote side rotated their pubkey during splice, update now */ + if (inflight->funding->splice_remote_funding) + channel->channel_info.remote_fundingkey = *inflight->funding->splice_remote_funding; + /* Update the reserve */ channel_update_reserve(channel, &channel->channel_info.their_config, diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 65c5b283780e..448d0c6a923d 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -262,7 +262,8 @@ static u8 *psbt_changeset_get_next(const tal_t *ctx, msg = towire_tx_add_input(ctx, cid, serial_id, prevtx, in->input.index, - in->input.sequence); + in->input.sequence, + NULL); tal_arr_remove(&set->added_ins, 0); return msg; @@ -1742,12 +1743,14 @@ static bool run_tx_interactive(struct state *state, struct bitcoin_tx *tx; struct bitcoin_outpoint outpoint; struct amount_sat amt; + struct tlv_tx_add_input_tlvs *tlvs; if (!fromwire_tx_add_input(tmpctx, msg, &cid, &serial_id, cast_const2(u8 **, &tx_bytes), - &outpoint.n, &sequence)) + &outpoint.n, &sequence, + &tlvs)) open_err_fatal(state, "Parsing tx_add_input %s", tal_hex(tmpctx, msg)); diff --git a/tests/fuzz/fuzz-wire-splice.c b/tests/fuzz/fuzz-wire-splice.c index 2b2adda94dbe..54b62d20feb5 100644 --- a/tests/fuzz/fuzz-wire-splice.c +++ b/tests/fuzz/fuzz-wire-splice.c @@ -5,7 +5,6 @@ struct splice { struct channel_id channel_id; - struct bitcoin_blkid chain_hash; s64 relative_satoshis; u32 funding_feerate_perkw; u32 locktime; @@ -14,7 +13,7 @@ struct splice { static void *encode(const tal_t *ctx, const struct splice *s) { - return towire_splice(ctx, &s->channel_id, &s->chain_hash, + return towire_splice(ctx, &s->channel_id, s->relative_satoshis, s->funding_feerate_perkw, s->locktime, &s->funding_pubkey); } @@ -23,7 +22,7 @@ static struct splice *decode(const tal_t *ctx, const void *p) { struct splice *s = tal(ctx, struct splice); - if (fromwire_splice(p, &s->channel_id, &s->chain_hash, + if (fromwire_splice(p, &s->channel_id, &s->relative_satoshis, &s->funding_feerate_perkw, &s->locktime, &s->funding_pubkey)) return s; diff --git a/tests/fuzz/fuzz-wire-splice_ack.c b/tests/fuzz/fuzz-wire-splice_ack.c index 2095ab4037df..ed57ee97e974 100644 --- a/tests/fuzz/fuzz-wire-splice_ack.c +++ b/tests/fuzz/fuzz-wire-splice_ack.c @@ -5,14 +5,13 @@ struct splice_ack { struct channel_id channel_id; - struct bitcoin_blkid chain_hash; s64 relative_satoshis; struct pubkey funding_pubkey; }; static void *encode(const tal_t *ctx, const struct splice_ack *s) { - return towire_splice_ack(ctx, &s->channel_id, &s->chain_hash, + return towire_splice_ack(ctx, &s->channel_id, s->relative_satoshis, &s->funding_pubkey); } @@ -20,7 +19,7 @@ static struct splice_ack *decode(const tal_t *ctx, const void *p) { struct splice_ack *s = tal(ctx, struct splice_ack); - if (fromwire_splice_ack(p, &s->channel_id, &s->chain_hash, + if (fromwire_splice_ack(p, &s->channel_id, &s->relative_satoshis, &s->funding_pubkey)) return s; return tal_free(s); diff --git a/tests/fuzz/fuzz-wire-tx_add_input.c b/tests/fuzz/fuzz-wire-tx_add_input.c index ad6a4f3fb64f..580ff88b1446 100644 --- a/tests/fuzz/fuzz-wire-tx_add_input.c +++ b/tests/fuzz/fuzz-wire-tx_add_input.c @@ -16,15 +16,17 @@ struct tx_add_input { static void *encode(const tal_t *ctx, const struct tx_add_input *s) { return towire_tx_add_input(ctx, &s->channel_id, s->serial_id, s->prevtx, - s->prevtx_vout, s->sequence); + s->prevtx_vout, s->sequence, NULL); } static struct tx_add_input *decode(const tal_t *ctx, const void *p) { struct tx_add_input *s = tal(ctx, struct tx_add_input); + struct tlv_tx_add_input_tlvs *tlvs; if (fromwire_tx_add_input(s, p, &s->channel_id, &s->serial_id, - &s->prevtx, &s->prevtx_vout, &s->sequence)) + &s->prevtx, &s->prevtx_vout, &s->sequence, + &tlvs)) return s; return tal_free(s); } diff --git a/tests/fuzz/fuzz-wire-tx_signatures.c b/tests/fuzz/fuzz-wire-tx_signatures.c index 839f2c2a22be..2b8e82e6f8c3 100644 --- a/tests/fuzz/fuzz-wire-tx_signatures.c +++ b/tests/fuzz/fuzz-wire-tx_signatures.c @@ -58,8 +58,8 @@ static bool equal(const struct tx_signatures *x, const struct tx_signatures *y) return false; assert(x->tlvs && y->tlvs); - return tal_arr_eq(x->tlvs->funding_outpoint_sig, - y->tlvs->funding_outpoint_sig); + return tal_arr_eq(x->tlvs->shared_input_signature, + y->tlvs->shared_input_signature); } void run(const u8 *data, size_t size) diff --git a/tests/test_restart.py b/tests/test_restart.py index 2acbd84af1ef..8ceef671cacf 100644 --- a/tests/test_restart.py +++ b/tests/test_restart.py @@ -17,5 +17,5 @@ def test_agressive_restart(node_factory, bitcoind): for _ in range(20): l1.rpc.stfu_channels([chan_id]) l1.rpc.abort_channels([chan_id]) - l1.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_REESTABLISH') - l2.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_REESTABLISH') + l1.daemon.wait_for_log(r'Restarting channeld after tx_abort') + l2.daemon.wait_for_log(r'Restarting channeld after tx_abort') diff --git a/tests/test_splicing.py b/tests/test_splicing.py index 02d3769cb670..99d08e1a15e8 100644 --- a/tests/test_splicing.py +++ b/tests/test_splicing.py @@ -230,10 +230,6 @@ def test_invalid_splice(node_factory, bitcoind): assert len(list(mempool.keys())) == 1 assert result['txid'] in list(mempool.keys()) - # Wait until nodes are reconnected - l1.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_REESTABLISH') - l2.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_REESTABLISH') - bitcoind.generate_block(6, wait_for_mempool=1) l2.daemon.wait_for_log(r'CHANNELD_AWAITING_SPLICE to CHANNELD_NORMAL') diff --git a/tests/test_splicing_disconnect.py b/tests/test_splicing_disconnect.py index 7fdb834f6620..e4553d425ffa 100644 --- a/tests/test_splicing_disconnect.py +++ b/tests/test_splicing_disconnect.py @@ -104,11 +104,8 @@ def test_splice_disconnect_commit(node_factory, bitcoind, executor): # Splice should be abandoned via tx_abort # Wait until nodes are reconnected - l1.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_REESTABLISH') - l2.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_REESTABLISH') - - l1.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_READY') - l2.daemon.wait_for_log(r'peer_in WIRE_CHANNEL_READY') + l1.daemon.wait_for_log(r'billboard: Channel ready for use.') + l2.daemon.wait_for_log(r'billboard: Channel ready for use.') # Check that the splice doesn't generate a unilateral close transaction time.sleep(5) diff --git a/tests/utils.py b/tests/utils.py index fd96c319d128..ddcc4bb1bace 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -45,7 +45,7 @@ def expected_peer_features(extra=[]): # option_dual_fund features += [29] if EXPERIMENTAL_SPLICING: - features += [163] # option_experimental_splice + features += [63] # option_splice if TEST_NETWORK != 'liquid-regtest': # Anchors, except for elements features += [23] @@ -61,7 +61,7 @@ def expected_node_features(extra=[]): # option_dual_fund features += [29] if EXPERIMENTAL_SPLICING: - features += [163] # option_experimental_splice + features += [63] # option_splice if TEST_NETWORK != 'liquid-regtest': # Anchors, except for elements features += [23] diff --git a/wallet/db.c b/wallet/db.c index 5b09cd4dfbc5..161d67c4480b 100644 --- a/wallet/db.c +++ b/wallet/db.c @@ -1027,6 +1027,7 @@ static struct migration dbmigrations[] = { " keyidx BIGINT," " addrtype INTEGER)"), NULL}, {NULL, insert_addrtype_to_addresses}, + {SQL("ALTER TABLE channel_funding_inflights ADD remote_funding BLOB DEFAULT NULL;"), NULL}, }; /** diff --git a/wallet/test/run-db.c b/wallet/test/run-db.c index b0820aa9ffaa..67243c7a7b17 100644 --- a/wallet/test/run-db.c +++ b/wallet/test/run-db.c @@ -213,6 +213,7 @@ struct chain_coin_mvt *new_coin_wallet_deposit(const tal_t *ctx UNNEEDED, { fprintf(stderr, "new_coin_wallet_deposit called!\n"); abort(); } /* Generated stub for new_inflight */ struct channel_inflight *new_inflight(struct channel *channel UNNEEDED, + struct pubkey *remote_funding UNNEEDED, const struct bitcoin_outpoint *funding_outpoint UNNEEDED, u32 funding_feerate UNNEEDED, struct amount_sat funding_sat UNNEEDED, diff --git a/wallet/test/run-wallet.c b/wallet/test/run-wallet.c index a534bc3f6289..e21585083fce 100644 --- a/wallet/test/run-wallet.c +++ b/wallet/test/run-wallet.c @@ -2019,7 +2019,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) memset(&outpoint, 1, sizeof(outpoint)); mempat(&sig.s, sizeof(sig.s)); - inflight = new_inflight(chan, &outpoint, 253, + inflight = new_inflight(chan, NULL, &outpoint, 253, funding_sats, our_sats, funding_psbt, @@ -2046,7 +2046,7 @@ static bool test_channel_inflight_crud(struct lightningd *ld, const tal_t *ctx) our_sats = AMOUNT_SAT(555555); memset(&outpoint, 2, sizeof(outpoint)); mempat(&sig.s, sizeof(sig.s)); - inflight = new_inflight(chan, &outpoint, 300, + inflight = new_inflight(chan, NULL, &outpoint, 300, funding_sats, our_sats, funding_psbt, diff --git a/wallet/wallet.c b/wallet/wallet.c index 21ee7e09c3ec..cb79c32cc0b7 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -1231,8 +1231,9 @@ void wallet_inflight_add(struct wallet *w, struct channel_inflight *inflight) ", splice_amnt" ", i_am_initiator" ", force_sign_first" + ", remote_funding" ") VALUES (" - "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); + "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);")); db_bind_u64(stmt, inflight->channel->dbid); db_bind_txid(stmt, &inflight->funding->outpoint.txid); @@ -1271,6 +1272,10 @@ void wallet_inflight_add(struct wallet *w, struct channel_inflight *inflight) db_bind_s64(stmt, inflight->funding->splice_amnt); db_bind_int(stmt, inflight->i_am_initiator); db_bind_int(stmt, inflight->force_sign_first); + if (inflight->funding->splice_remote_funding) + db_bind_pubkey(stmt, inflight->funding->splice_remote_funding); + else + db_bind_null(stmt); db_exec_prepared_v2(stmt); assert(!stmt->error); @@ -1348,6 +1353,7 @@ static struct channel_inflight * wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, struct channel *chan) { + struct pubkey *remote_funding = NULL; struct amount_sat funding_sat, our_funding_sat; struct amount_msat lease_fee; struct bitcoin_outpoint funding; @@ -1391,11 +1397,16 @@ wallet_stmt2inflight(struct wallet *w, struct db_stmt *stmt, db_col_ignore(stmt, "lease_satoshi"); } + if (!db_col_is_null(stmt, "remote_funding")) { + remote_funding = tal(tmpctx, struct pubkey); + db_col_pubkey(stmt, "remote_funding", remote_funding); + } + splice_amnt = db_col_s64(stmt, "splice_amnt"); i_am_initiator = db_col_int(stmt, "i_am_initiator"); force_sign_first = db_col_int(stmt, "force_sign_first"); - inflight = new_inflight(chan, &funding, + inflight = new_inflight(chan, remote_funding, &funding, db_col_int(stmt, "funding_feerate"), funding_sat, our_funding_sat, @@ -1461,6 +1472,7 @@ static bool wallet_channel_load_inflights(struct wallet *w, ", splice_amnt" ", i_am_initiator" ", force_sign_first" + ", remote_funding" " FROM channel_funding_inflights" " WHERE channel_id = ?" " ORDER BY funding_feerate")); diff --git a/wire/peer_wire.csv b/wire/peer_wire.csv index 6543e34ee4f4..c36d90807b08 100644 --- a/wire/peer_wire.csv +++ b/wire/peer_wire.csv @@ -44,6 +44,9 @@ msgdata,tx_add_input,prevtx_len,u16, msgdata,tx_add_input,prevtx,byte,prevtx_len msgdata,tx_add_input,prevtx_vout,u32, msgdata,tx_add_input,sequence,u32, +msgdata,tx_add_input,tlvs,tx_add_input_tlvs, +tlvtype,tx_add_input_tlvs,shared_input_txid,0 +tlvdata,tx_add_input_tlvs,shared_input_txid,funding_txid,sha256, msgtype,tx_add_output,67 msgdata,tx_add_output,channel_id,channel_id, msgdata,tx_add_output,serial_id,u64, @@ -67,8 +70,8 @@ msgdata,tx_signatures,tlvs,txsigs_tlvs, subtype,witness subtypedata,witness,len,u16, subtypedata,witness,witness_data,byte,len -tlvtype,txsigs_tlvs,funding_outpoint_sig,0 -tlvdata,txsigs_tlvs,funding_outpoint_sig,sig,byte,... +tlvtype,txsigs_tlvs,shared_input_signature,0 +tlvdata,txsigs_tlvs,shared_input_signature,signature,signature, msgtype,tx_init_rbf,72 msgdata,tx_init_rbf,channel_id,channel_id, msgdata,tx_init_rbf,locktime,u32, @@ -208,16 +211,14 @@ subtypedata,lease_rates,channel_fee_max_base_msat,tu32, msgtype,stfu,2 msgdata,stfu,channel_id,channel_id, msgdata,stfu,initiator,u8, -msgtype,splice,75 +msgtype,splice,80 msgdata,splice,channel_id,channel_id, -msgdata,splice,chain_hash,chain_hash, msgdata,splice,relative_satoshis,s64, msgdata,splice,funding_feerate_perkw,u32, msgdata,splice,locktime,u32, msgdata,splice,funding_pubkey,point, -msgtype,splice_ack,76 +msgtype,splice_ack,81 msgdata,splice_ack,channel_id,channel_id, -msgdata,splice_ack,chain_hash,chain_hash, msgdata,splice_ack,relative_satoshis,s64, msgdata,splice_ack,funding_pubkey,point, msgtype,splice_locked,77, @@ -268,7 +269,8 @@ msgdata,commitment_signed,num_htlcs,u16, msgdata,commitment_signed,htlc_signature,signature,num_htlcs msgdata,commitment_signed,splice_channel_id,commitment_signed_tlvs, tlvtype,commitment_signed_tlvs,splice_info,0 -tlvdata,commitment_signed_tlvs,splice_info,splice_channel_id,channel_id, +tlvdata,commitment_signed_tlvs,splice_info,batch_size,u16, +tlvdata,commitment_signed_tlvs,splice_info,funding_txid,channel_id, msgtype,revoke_and_ack,133 msgdata,revoke_and_ack,channel_id,channel_id, msgdata,revoke_and_ack,per_commitment_secret,byte,32 diff --git a/wire/test/run-peer-wire.c b/wire/test/run-peer-wire.c index ad5379580b5d..8700d201e01b 100644 --- a/wire/test/run-peer-wire.c +++ b/wire/test/run-peer-wire.c @@ -792,12 +792,19 @@ static bool update_fail_htlc_eq(const struct msg_update_fail_htlc *a, && eq_var(a, b, reason); } +static bool tlv_splice_info_eq(const struct tlv_commitment_signed_tlvs_splice_info *a, + const struct tlv_commitment_signed_tlvs_splice_info *b) +{ + return eq_field(a, b, batch_size) + && eq_field(a, b, funding_txid); +} + static bool commitment_signed_eq(const struct msg_commitment_signed *a, const struct msg_commitment_signed *b) { return eq_upto(a, b, htlc_signature) && eq_var(a, b, htlc_signature) - && eq_tlv(a, b, splice_info, channel_id_eq); + && eq_tlv(a, b, splice_info, tlv_splice_info_eq); } static bool funding_signed_eq(const struct msg_funding_signed *a, @@ -1019,8 +1026,9 @@ int main(int argc, char *argv[]) cs.htlc_signature = tal_arr(ctx, secp256k1_ecdsa_signature, 2); memset(cs.htlc_signature, 2, sizeof(secp256k1_ecdsa_signature)*2); cs.tlvs = tlv_commitment_signed_tlvs_new(tmpctx); - cs.tlvs->splice_info = tal(ctx, struct channel_id); - set_cid(cs.tlvs->splice_info); + cs.tlvs->splice_info = tal(ctx, struct tlv_commitment_signed_tlvs_splice_info); + cs.tlvs->splice_info->batch_size = 1; + set_cid(&cs.tlvs->splice_info->funding_txid); msg = towire_struct_commitment_signed(ctx, &cs); cs2 = fromwire_struct_commitment_signed(ctx, msg);