Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 109 additions & 15 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -1814,7 +1814,7 @@ static void splice_abort(struct peer *peer, const char *fmt, ...)
reason = tal_vfmt(NULL, fmt, ap);
va_end(ap);

if (have_i_signed_inflight(peer, inflight))
if (inflight && inflight->i_sent_sigs)
peer_failed_err(peer->pps, &peer->channel_id,
"I needed to abort a splice where I have already"
" sent my signatures");
Expand Down Expand Up @@ -3283,7 +3283,10 @@ static struct amount_sat check_balances(struct peer *peer,
if (!amount_msat_add_sat_s64(&funding_amount, funding_amount,
peer->splicing->opener_relative))
splice_abort(peer, "Splice initiator did not provide enough"
" funding");
" funding, funding_amount: %s, opener_relative:"
" %"PRIu64,
fmt_amount_msat(tmpctx, funding_amount),
peer->splicing->opener_relative);
if (!amount_msat_add_sat_s64(&out[TX_INITIATOR], out[TX_INITIATOR],
peer->splicing->opener_relative))
peer_failed_warn(peer->pps, &peer->channel_id,
Expand All @@ -3309,11 +3312,16 @@ static struct amount_sat check_balances(struct peer *peer,
" amount. Initiator contributing %s but they"
" committed to %s. Pending offered HTLC"
" balance of %s is not available for this"
" operation.",
" operation. We are%s the opener. We began the"
" operation being owed/owing %s and expect"
" that amount to change %"PRIu64"000",
fmt_amount_msat(tmpctx, in[TX_INITIATOR]),
fmt_amount_msat(tmpctx, out[TX_INITIATOR]),
fmt_amount_msat(tmpctx,
pending_htlcs[TX_INITIATOR]));
pending_htlcs[TX_INITIATOR]),
opener ? "" : " not",
fmt_amount_msat(tmpctx, peer->channel->view->owed[opener ? LOCAL : REMOTE]),
peer->splicing->opener_relative);
}

if (!amount_msat_sub(&initiator_fee, in[TX_INITIATOR], out[TX_INITIATOR]))
Expand Down Expand Up @@ -3482,6 +3490,29 @@ static void update_view_from_inflights(struct peer *peer)
}
}

static size_t count_inputs_with_exclusions(struct wally_psbt *psbt,
enum tx_role role_to_ignore,
u32 input_index_to_ignore)
{
size_t result = 0;
for (size_t i = 0; i < psbt->num_inputs; i++) {
struct wally_psbt_input *in = &psbt->inputs[i];
u64 in_serial;

if (!psbt_get_serial_id(&in->unknowns, &in_serial))
status_broken("PSBT input %zu missing serial_id"
" %s", i, fmt_wally_psbt(tmpctx, psbt));
if (in_serial % 2 == role_to_ignore)
continue;

if (i == input_index_to_ignore)
continue;

result++;
}
return result;
}

/* Called to finish an ongoing splice OR on restart from channel_reestablish. */
static void resume_splice_negotiation(struct peer *peer,
bool send_commitments,
Expand Down Expand Up @@ -3559,7 +3590,8 @@ static void resume_splice_negotiation(struct peer *peer,
msg = towire_channeld_update_inflight(NULL, current_psbt,
their_commit->tx,
&their_commit->commit_signature,
inflight->locked_scid);
inflight->locked_scid,
inflight->i_sent_sigs);
wire_sync_write(MASTER_FD, take(msg));
}

Expand Down Expand Up @@ -3625,12 +3657,14 @@ static void resume_splice_negotiation(struct peer *peer,

psbt_txid(tmpctx, current_psbt, &final_txid, NULL);

inflight->i_sent_sigs = send_signature;
if (do_i_sign_first(peer, current_psbt, our_role,
inflight->force_sign_first)
&& send_signature) {
msg = towire_channeld_update_inflight(NULL, current_psbt,
NULL, NULL,
inflight->locked_scid);
inflight->locked_scid,
inflight->i_sent_sigs);
wire_sync_write(MASTER_FD, take(msg));

msg = towire_channeld_splice_sending_sigs(tmpctx, &final_txid);
Expand Down Expand Up @@ -3774,12 +3808,20 @@ static void resume_splice_negotiation(struct peer *peer,
if (i == splice_funding_index)
continue;

if (j == tal_count(inws))
if (j == tal_count(inws)) {
peer_failed_warn(peer->pps,
&peer->channel_id,
"Mismatch witness stack count."
" Most likely you are missing"
" signatures.");
" signatures. We have %zu"
" remote inputs needing sigs"
" and you sent %zu witness"
" bundles.",
count_inputs_with_exclusions(current_psbt,
our_role,
splice_funding_index),
tal_count(inws));
}

psbt_finalize_input(current_psbt, in,
inws[j++]);
Expand All @@ -3796,11 +3838,12 @@ static void resume_splice_negotiation(struct peer *peer,
wit_stack);
}

if (recv_signature) {
if (recv_signature || send_signature) {
/* We let core validate our peer's signatures are correct. */
msg = towire_channeld_update_inflight(NULL, current_psbt, NULL,
NULL,
inflight->locked_scid);
inflight->locked_scid,
inflight->i_sent_sigs);
wire_sync_write(MASTER_FD, take(msg));
}

Expand Down Expand Up @@ -4065,7 +4108,8 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg)
peer->splicing->accepter_relative,
ictx->current_psbt,
false,
peer->splicing->force_sign_first);
peer->splicing->force_sign_first,
false);

master_wait_sync_reply(tmpctx, peer, take(msg),
WIRE_CHANNELD_GOT_INFLIGHT);
Expand All @@ -4083,6 +4127,7 @@ static void splice_accepter(struct peer *peer, const u8 *inmsg)
new_inflight->i_am_initiator = false;
new_inflight->force_sign_first = peer->splicing->force_sign_first;
new_inflight->locked_scid = NULL;
new_inflight->i_sent_sigs = false;

current_push_val = relative_splice_balance_fundee(peer, our_role,ictx->current_psbt,
outpoint.n, splice_funding_index);
Expand Down Expand Up @@ -4242,6 +4287,8 @@ static void splice_initiator_user_finalized(struct peer *peer)
u8 *outmsg;
struct interactivetx_context *ictx;
struct bitcoin_tx *prev_tx;
struct bitcoin_tx *bitcoin_tx;
struct bitcoin_signature splice_sig;
bool sign_first;
char *error;
u32 chan_output_index, splice_funding_index;
Expand All @@ -4253,6 +4300,7 @@ static void splice_initiator_user_finalized(struct peer *peer)
struct amount_msat current_push_val;
const enum tx_role our_role = TX_INITIATOR;
u8 *abort_msg;
const u8* msg;

/* We must loading the funding tx as our previous utxo */
prev_tx = bitcoin_tx_from_txid(peer, peer->channel->funding.txid);
Expand Down Expand Up @@ -4301,6 +4349,44 @@ static void splice_initiator_user_finalized(struct peer *peer)

psbt_elements_normalize_fees(ictx->current_psbt);

/* We have to sign the shared output early (here) for cases where we are
* splicing between multiple channels simultaneously. This is so the
* we can build a complete `tx_signatures` message when there are two
* or more shared outputs between mulitple peers */

splice_sig.sighash_type = SIGHASH_ALL;

bitcoin_tx = bitcoin_tx_with_psbt(tmpctx, ictx->current_psbt);

status_info("Splice pre-signing tx: %s",
tal_hex(tmpctx, linearize_tx(tmpctx, bitcoin_tx)));

msg = towire_hsmd_sign_splice_tx(tmpctx, bitcoin_tx,
&peer->channel->funding_pubkey[REMOTE],
splice_funding_index);

msg = hsm_req(tmpctx, take(msg));
if (!fromwire_hsmd_sign_tx_reply(msg, &splice_sig))
status_failed(STATUS_FAIL_HSM_IO,
"Reading sign_splice_tx reply: %s",
tal_hex(tmpctx, msg));

/* Set the splice_sig on the splice funding tx psbt */
if (!psbt_input_set_signature(ictx->current_psbt, splice_funding_index,
&peer->channel->funding_pubkey[LOCAL],
&splice_sig))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Unable to pre-set signature internally "
"funding_index: %d "
"my pubkey: %s "
"my signature: %s "
"psbt: %s",
splice_funding_index,
fmt_pubkey(tmpctx,
&peer->channel->funding_pubkey[LOCAL]),
fmt_bitcoin_signature(tmpctx, &splice_sig),
fmt_wally_psbt(tmpctx, ictx->current_psbt));

status_debug("Splice adding inflight: %s",
fmt_wally_psbt(tmpctx, ictx->current_psbt));

Expand All @@ -4315,7 +4401,8 @@ static void splice_initiator_user_finalized(struct peer *peer)
peer->splicing->opener_relative,
ictx->current_psbt,
true,
peer->splicing->force_sign_first);
peer->splicing->force_sign_first,
false);

master_wait_sync_reply(tmpctx, peer, take(outmsg),
WIRE_CHANNELD_GOT_INFLIGHT);
Expand All @@ -4332,6 +4419,7 @@ static void splice_initiator_user_finalized(struct peer *peer)
new_inflight->i_am_initiator = true;
new_inflight->force_sign_first = peer->splicing->force_sign_first;
new_inflight->locked_scid = NULL;
new_inflight->i_sent_sigs = false;

audit_psbt(ictx->current_psbt, ictx->current_psbt);

Expand Down Expand Up @@ -4363,7 +4451,8 @@ static void splice_initiator_user_finalized(struct peer *peer)
outmsg = towire_channeld_update_inflight(NULL, new_inflight->psbt,
their_commit->tx,
&their_commit->commit_signature,
new_inflight->locked_scid);
new_inflight->locked_scid,
new_inflight->i_sent_sigs);
wire_sync_write(MASTER_FD, take(outmsg));

sign_first = do_i_sign_first(peer, new_inflight->psbt, our_role,
Expand Down Expand Up @@ -4434,6 +4523,9 @@ static void splice_initiator_user_update(struct peer *peer, const u8 *inmsg)

/* If there no are no changes, we consider the splice user finalized */
if (!interactivetx_has_changes(ictx, ictx->desired_psbt)) {
peer->splicing->current_psbt = tal_free(peer->splicing->current_psbt);
peer->splicing->current_psbt = clone_psbt(peer->splicing,
ictx->desired_psbt);
splice_initiator_user_finalized(peer);
tal_steal(last_inflight(peer), last_inflight(peer)->psbt);
return;
Expand Down Expand Up @@ -4557,7 +4649,8 @@ static void splice_initiator_user_signed(struct peer *peer, const u8 *inmsg)
outmsg = towire_channeld_update_inflight(NULL, inflight->psbt,
inflight->last_tx,
&inflight->last_sig,
inflight->locked_scid);
inflight->locked_scid,
inflight->i_sent_sigs);

wire_sync_write(MASTER_FD, take(outmsg));

Expand Down Expand Up @@ -5871,7 +5964,8 @@ static void handle_funding_depth(struct peer *peer, const u8 *msg)
inflight->psbt,
NULL,
NULL,
inflight->locked_scid);
inflight->locked_scid,
inflight->i_sent_sigs);
wire_sync_write(MASTER_FD, take(msg));
inflight_match = inflight;
}
Expand Down
2 changes: 2 additions & 0 deletions channeld/channeld_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ msgdata,channeld_add_inflight,splice_amount,s64,
msgdata,channeld_add_inflight,psbt,wally_psbt,
msgdata,channeld_add_inflight,i_am_initiator,bool,
msgdata,channeld_add_inflight,force_sign_first,bool,
msgdata,channeld_add_inflight,i_sent_sigs,bool,

# master->channeld: Inflight saved successfully
msgtype,channeld_got_inflight,7217
Expand All @@ -272,6 +273,7 @@ msgdata,channeld_update_inflight,psbt,wally_psbt,
msgdata,channeld_update_inflight,last_tx,?bitcoin_tx,
msgdata,channeld_update_inflight,last_sig,?bitcoin_signature,
msgdata,channeld_update_inflight,locked_scid,?short_channel_id,
msgdata,channeld_update_inflight,i_sent_sigs,bool,

# channeld->master: A funding error has occured
msgtype,channeld_splice_funding_error,7220
Expand Down
2 changes: 2 additions & 0 deletions channeld/inflight.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ struct inflight *fromwire_inflight(const tal_t *ctx, const u8 **cursor, size_t *
else {
inflight->locked_scid = NULL;
}
inflight->i_sent_sigs = fromwire_bool(cursor, max);

return inflight;
}
Expand All @@ -56,4 +57,5 @@ void towire_inflight(u8 **pptr, const struct inflight *inflight)
towire_u8(pptr, inflight->locked_scid ? 1 : 0);
if (inflight->locked_scid)
towire_short_channel_id(pptr, *inflight->locked_scid);
towire_bool(pptr, inflight->i_sent_sigs);
}
1 change: 1 addition & 0 deletions channeld/inflight.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct inflight {
bool i_am_initiator;
bool force_sign_first;
struct short_channel_id *locked_scid;
bool i_sent_sigs;
};

struct inflight *fromwire_inflight(const tal_t *ctx, const u8 **cursor, size_t *max);
Expand Down
50 changes: 50 additions & 0 deletions common/interactivetx.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
#include <common/subdaemon.h>
#include <common/wire_error.h>

#ifndef SUPERVERBOSE
#define SUPERVERBOSE(...)
#endif

/*
* BOLT #2:
* The receiving node: ...
Expand Down Expand Up @@ -197,6 +201,18 @@ static u8 *read_next_msg(const tal_t *ctx,
}
}

#define SHA_FMT \
"%02x%02x%02x%02x%02x%02x%02x%02x" \
"%02x%02x%02x%02x%02x%02x%02x%02x" \
"%02x%02x%02x%02x%02x%02x%02x%02x" \
"%02x%02x%02x%02x%02x%02x%02x%02x"

#define SHA_VALS(e) \
e[0], e[1], e[2], e[3], e[4], e[5], e[6], e[7], \
e[8], e[9], e[10], e[11], e[12], e[13], e[14], e[15], \
e[16], e[17], e[18], e[19], e[20], e[21], e[22], e[23], \
e[24], e[25], e[25], e[26], e[28], e[29], e[30], e[31]

static char *send_next(const tal_t *ctx,
struct interactivetx_context *ictx,
bool *finished)
Expand Down Expand Up @@ -268,6 +284,10 @@ static char *send_next(const tal_t *ctx,
return "interactivetx RM_INPUT PSBT has invalid"
" serial_id.";

SUPERVERBOSE("Removing input "SHA_FMT" with serial_id %s",
SHA_VALS(set->rm_ins[0].input.txhash),
tal_hexstr(ctx, &serial_id, sizeof(serial_id)));

msg = towire_tx_remove_input(NULL, cid, serial_id);

tal_arr_remove(&set->rm_ins, 0);
Expand Down Expand Up @@ -404,6 +424,36 @@ char *process_interactivetx_updates(const tal_t *ctx,
if (!next_psbt)
next_psbt = ictx->current_psbt;

SUPERVERBOSE("itx get_changes %zu inputs -> %zu inputs",
ictx->current_psbt->num_inputs,
next_psbt->num_inputs);

SUPERVERBOSE("current_psbt inputs:");
for(size_t i = 0; i < ictx->current_psbt->num_inputs; i++) {
u64 serial_id;
if (!psbt_get_serial_id(&ictx->current_psbt->inputs[i].unknowns,
&serial_id))
return "interactivetx ADD_INPUT PSBT has invalid"
" serial_id.";
SUPERVERBOSE("txhash: "SHA_FMT", index: %"PRIu32", serial_id: %s",
SHA_VALS(ictx->current_psbt->inputs[i].txhash),
ictx->current_psbt->inputs[i].index,
tal_hexstr(ctx, &serial_id, sizeof(serial_id)));
}

SUPERVERBOSE("next_psbt inputs:");
for(size_t i = 0; i < next_psbt->num_inputs; i++) {
u64 serial_id;
if (!psbt_get_serial_id(&next_psbt->inputs[i].unknowns,
&serial_id))
return "interactivetx ADD_INPUT PSBT has invalid"
" serial_id.";
SUPERVERBOSE("txhash: "SHA_FMT", index: %"PRIu32", serial_id: %s",
SHA_VALS(next_psbt->inputs[i].txhash),
next_psbt->inputs[i].index,
tal_hexstr(ctx, &serial_id, sizeof(serial_id)));
}

ictx->change_set = get_changes(ctx, ictx, next_psbt);

/* If current_psbt and next_psbt are the same, dont double free it!
Expand Down
Loading
Loading