diff --git a/channeld/channeld.c b/channeld/channeld.c index 11046ba7794e..a18fc54c6438 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -3610,8 +3610,9 @@ static void resume_splice_negotiation(struct peer *peer, " Most likely you are missing" " signatures."); - psbt_finalize_input(current_psbt, in, - inws[j++]); + tal_wally_start(); + psbt_finalize_input(current_psbt, in, inws[j++]); + tal_wally_end(current_psbt); } final_tx = bitcoin_tx_with_psbt(tmpctx, current_psbt); @@ -3654,6 +3655,13 @@ static void resume_splice_negotiation(struct peer *peer, new_output_index); wire_sync_write(MASTER_FD, take(msg)); } + + size_t dummy; + psbt_get_bytes(NULL, inflight->psbt, &dummy); + psbt_get_bytes(NULL, current_psbt, &dummy); + clone_psbt(NULL, inflight->psbt); + clone_psbt(NULL, current_psbt); + assert(inflight->psbt == current_psbt); } static struct inflight *inflights_new(struct peer *peer) @@ -3841,7 +3849,7 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) funding_feerate_perkw, both_amount, peer->splicing->accepter_relative, - ictx->current_psbt, + clone_psbt(tmpctx, ictx->current_psbt), false, peer->splicing->force_sign_first); @@ -3862,15 +3870,35 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg) new_inflight->force_sign_first = peer->splicing->force_sign_first; new_inflight->is_locked = false; - current_push_val = relative_splice_balance_fundee(peer, our_role,ictx->current_psbt, + size_t dummy; + psbt_get_bytes(NULL, new_inflight->psbt, &dummy); + + current_push_val = relative_splice_balance_fundee(peer, our_role, ictx->current_psbt, outpoint.n, splice_funding_index); + + psbt_get_bytes(NULL, new_inflight->psbt, &dummy); + update_hsmd_with_splice(peer, new_inflight, our_role, current_push_val); + psbt_get_bytes(NULL, new_inflight->psbt, &dummy); + update_view_from_inflights(peer); + psbt_get_bytes(NULL, new_inflight->psbt, &dummy); + peer->splice_state->count++; + psbt_get_bytes(NULL, new_inflight->psbt, &dummy); + resume_splice_negotiation(peer, true, true, true, true); + + psbt_get_bytes(NULL, new_inflight->psbt, &dummy); + + struct wally_psbt *old = new_inflight->psbt; + new_inflight->psbt = clone_psbt(new_inflight, ictx->current_psbt); + clean_tmpctx(); + + psbt_get_bytes(NULL, new_inflight->psbt, &dummy); } /* splice_initiator runs when splice_ack is received by the other side. It @@ -3992,6 +4020,7 @@ static void splice_initiator_user_finalized(struct peer *peer) char *error; u32 chan_output_index, splice_funding_index; struct wally_psbt_output *new_chan_output; + struct wally_psbt *psbt; struct inflight *new_inflight; struct bitcoin_txid current_psbt_txid; struct amount_sat both_amount; @@ -4003,7 +4032,7 @@ static void splice_initiator_user_finalized(struct peer *peer) /* 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, + ictx = new_interactivetx_context(NULL, our_role, peer->pps, peer->channel_id); ictx->next_update_fn = next_splice_step; @@ -4015,60 +4044,82 @@ 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; + clone_psbt(NULL, ictx->current_psbt); + 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, + clone_psbt(NULL, ictx->current_psbt); + + error = process_interactivetx_updates(ictx, ictx, &peer->splicing->received_tx_complete, &abort_msg); if (error) peer_failed_warn(peer->pps, &peer->channel_id, "Splice interactivetx error: %s", error); + clone_psbt(NULL, ictx->current_psbt); // dustin + check_tx_abort(peer, abort_msg); + psbt = ictx->current_psbt; + + clone_psbt(NULL, psbt); + /* With pause_when_complete fase, this assert should never fail */ assert(peer->splicing->received_tx_complete); peer->splicing->sent_tx_complete = true; - psbt_sort_by_serial_id(ictx->current_psbt); + clone_psbt(NULL, psbt); - new_chan_output = find_channel_output(peer, ictx->current_psbt, + new_chan_output = find_channel_output(peer, psbt, &chan_output_index, &peer->splicing->remote_funding_pubkey); + + clone_psbt(NULL, psbt); - splice_funding_index = find_channel_funding_input(ictx->current_psbt, + splice_funding_index = find_channel_funding_input(psbt, &peer->channel->funding); + + clone_psbt(NULL, psbt); // lisa - both_amount = check_balances(peer, our_role, ictx->current_psbt, + both_amount = check_balances(peer, our_role, psbt, chan_output_index, splice_funding_index); new_chan_output->amount = both_amount.satoshis; /* Raw: type conv */ + + clone_psbt(NULL, psbt); - psbt_elements_normalize_fees(ictx->current_psbt); + psbt_elements_normalize_fees(psbt); + + clone_psbt(NULL, psbt); status_debug("Splice adding inflight: %s", - fmt_wally_psbt(tmpctx, ictx->current_psbt)); + fmt_wally_psbt(tmpctx, psbt)); - psbt_txid(tmpctx, ictx->current_psbt, ¤t_psbt_txid, NULL); + psbt_txid(ictx, psbt, ¤t_psbt_txid, NULL); + + clone_psbt(NULL, psbt); - outmsg = towire_channeld_add_inflight(tmpctx, + outmsg = towire_channeld_add_inflight(NULL, &peer->splicing->remote_funding_pubkey, ¤t_psbt_txid, chan_output_index, peer->splicing->feerate_per_kw, amount_sat(new_chan_output->amount), peer->splicing->opener_relative, - ictx->current_psbt, + psbt, true, peer->splicing->force_sign_first); + + clone_psbt(NULL, psbt); master_wait_sync_reply(tmpctx, peer, take(outmsg), WIRE_CHANNELD_GOT_INFLIGHT); new_inflight = inflights_new(peer); - psbt_txid(tmpctx, ictx->current_psbt, &new_inflight->outpoint.txid, + psbt_txid(new_inflight, psbt, &new_inflight->outpoint.txid, NULL); new_inflight->remote_funding = peer->splicing->remote_funding_pubkey; new_inflight->outpoint.n = chan_output_index; @@ -4084,7 +4135,7 @@ static void splice_initiator_user_finalized(struct peer *peer) * normal in-memory copy of the psbt: peer->splicing/ictx->current_psbt. * Since we have to support using the inflight psbt anyway, we default * to it. */ - new_inflight->psbt = clone_psbt(new_inflight, ictx->current_psbt); + new_inflight->psbt = clone_psbt(new_inflight, psbt); current_push_val = relative_splice_balance_fundee(peer, our_role, new_inflight->psbt, @@ -4113,14 +4164,23 @@ static void splice_initiator_user_finalized(struct peer *peer) sign_first = do_i_sign_first(peer, new_inflight->psbt, our_role, peer->splicing->force_sign_first); + assert(new_inflight->psbt); + if (!sign_first) resume_splice_negotiation(peer, false, false, false, true); + assert(new_inflight->psbt); + struct wally_psbt *old_psbt = new_inflight->psbt; + new_inflight->psbt = clone_psbt(new_inflight, new_inflight->psbt); + tal_free(old_psbt); + outmsg = towire_channeld_splice_confirmed_update(NULL, new_inflight->psbt, true, !sign_first); wire_sync_write(MASTER_FD, take(outmsg)); + + tal_free(ictx); } /* During a splice the user may call splice_update mulitple times adding @@ -4141,7 +4201,7 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg) return; } - ictx = new_interactivetx_context(tmpctx, TX_INITIATOR, + ictx = new_interactivetx_context(NULL, TX_INITIATOR, peer->pps, peer->channel_id); if (!fromwire_channeld_splice_update(ictx, inmsg, &ictx->desired_psbt)) @@ -4152,6 +4212,7 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg) " splice when not in" " splice mode."); wire_sync_write(MASTER_FD, take(msg)); + tal_free(ictx); return; } @@ -4177,10 +4238,11 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg) if (!interactivetx_has_changes(ictx, ictx->desired_psbt)) { splice_initiator_user_finalized(peer); tal_steal(last_inflight(peer), last_inflight(peer)->psbt); + tal_free(ictx); return; } - error = process_interactivetx_updates(tmpctx, ictx, + error = process_interactivetx_updates(ictx, ictx, &peer->splicing->received_tx_complete, &abort_msg); if (error) @@ -4201,9 +4263,10 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg) /* Peer may have modified our PSBT so we return it to the user here */ outmsg = towire_channeld_splice_confirmed_update(NULL, - ictx->current_psbt, + peer->splicing->current_psbt, false, false); wire_sync_write(MASTER_FD, take(outmsg)); + tal_free(ictx); } /* This occurs when the user has signed the final version of the PSBT. At this @@ -5650,6 +5713,8 @@ static void handle_funding_depth(struct peer *peer, const u8 *msg) for (size_t i = 0; i < tal_count(peer->splice_state->inflights); i++) { struct inflight *inflight = peer->splice_state->inflights[i]; + size_t dummy; + psbt_get_bytes(NULL, inflight->psbt, &dummy); if (bitcoin_txid_eq(&inflight->outpoint.txid, &txid)) { inflight->is_locked = true; diff --git a/common/interactivetx.c b/common/interactivetx.c index 7050feef222c..bef57b476b60 100644 --- a/common/interactivetx.c +++ b/common/interactivetx.c @@ -391,19 +391,36 @@ char *process_interactivetx_updates(const tal_t *ctx, if (received_tx_complete) they_complete = *received_tx_complete; - /* Build change_set and handle PSBT variables */ - ictx->change_set = tal_free(ictx->change_set); + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); /* Call next_update_fn or default to 'desired_psbt' */ next_psbt = ictx->next_update_fn(ictx, ictx); + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + /* Returning NULL from next_update_fn is the same as using `current_psbt` * with no changes -- both indicate no changes */ if (!next_psbt) next_psbt = ictx->current_psbt; + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + ictx->change_set = get_changes(ctx, ictx, next_psbt); + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); // this fails + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + /* If current_psbt and next_psbt are the same, dont double free it! * Otherwise we advance `current_psbt` to `next_psbt` and begin * processing the change set in `ictx->change_set` */ @@ -414,6 +431,11 @@ char *process_interactivetx_updates(const tal_t *ctx, ictx->current_psbt = next_psbt; } + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + /* As initiator we always start with a single send to start it off */ if (ictx->our_role == TX_INITIATOR) { error = send_next(ctx, ictx, &we_complete); @@ -426,6 +448,11 @@ char *process_interactivetx_updates(const tal_t *ctx, } } + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + /* Loop through tx update turns with peer */ while (!(we_complete && they_complete)) { struct channel_id cid; @@ -439,10 +466,20 @@ char *process_interactivetx_updates(const tal_t *ctx, if (received_tx_complete) *received_tx_complete = false; + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + msg = read_next_msg(ctx, ictx, &error); if (error) return error; + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + t = fromwire_peektype(msg); switch (t) { case WIRE_TX_ADD_INPUT: { @@ -803,6 +840,11 @@ char *process_interactivetx_updates(const tal_t *ctx, send_next(ctx, ictx, &we_complete); } + if (ictx->current_psbt) + clone_psbt(NULL, ictx->current_psbt); + if (ictx->desired_psbt) + clone_psbt(NULL, ictx->desired_psbt); + /* Sort psbt! */ psbt_sort_by_serial_id(ictx->current_psbt); diff --git a/common/psbt_open.c b/common/psbt_open.c index a54085e61ee0..b4e8086ffd6a 100644 --- a/common/psbt_open.c +++ b/common/psbt_open.c @@ -285,79 +285,128 @@ struct psbt_changeset *psbt_get_changeset(const tal_t *ctx, size_t i = 0, j = 0; struct psbt_changeset *set; + clone_psbt(NULL, orig); + clone_psbt(NULL, new); + psbt_sort_by_serial_id(orig); + + clone_psbt(NULL, orig); + clone_psbt(NULL, new); + psbt_sort_by_serial_id(new); + clone_psbt(NULL, orig); + clone_psbt(NULL, new); + set = new_changeset(ctx); + clone_psbt(NULL, orig); + clone_psbt(NULL, new); + /* Find the input diff */ while (i < orig->num_inputs || j < new->num_inputs) { + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (i >= orig->num_inputs) { ADD(input, set->added_ins, new, j); j++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (j >= new->num_inputs) { ADD(input, set->rm_ins, orig, i); i++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); result = compare_serials(&orig->inputs[i].unknowns, &new->inputs[j].unknowns); + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (result == -1) { ADD(input, set->rm_ins, orig, i); i++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (result == 1) { ADD(input, set->added_ins, new, j); j++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (!input_identical(orig, i, new, j)) { ADD(input, set->rm_ins, orig, i); ADD(input, set->added_ins, new, j); } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); i++; j++; + clone_psbt(NULL, orig); + clone_psbt(NULL, new); } + + clone_psbt(NULL, orig); + clone_psbt(NULL, new); /* Find the output diff */ i = 0; j = 0; while (i < orig->num_outputs || j < new->num_outputs) { + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (i >= orig->num_outputs) { ADD(output, set->added_outs, new, j); j++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (j >= new->num_outputs) { ADD(output, set->rm_outs, orig, i); i++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); result = compare_serials(&orig->outputs[i].unknowns, &new->outputs[j].unknowns); + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (result == -1) { ADD(output, set->rm_outs, orig, i); i++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (result == 1) { ADD(output, set->added_outs, new, j); j++; continue; } + clone_psbt(NULL, orig); + clone_psbt(NULL, new); if (!output_identical(orig, i, new, j)) { ADD(output, set->rm_outs, orig, i); ADD(output, set->added_outs, new, j); } i++; j++; + clone_psbt(NULL, orig); + clone_psbt(NULL, new); } + clone_psbt(NULL, orig); // crash here + clone_psbt(NULL, new); + return set; } diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 4a9275840339..27f37de7c5e3 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -452,6 +452,8 @@ static void handle_splice_confirmed_update(struct lightningd *ld, return; } + assert(psbt); + if (psbt->version != cc->user_psbt_ver && !psbt_set_version(psbt, cc->user_psbt_ver)) channel_internal_error(channel, "Splice failed to convert from"