mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
splice: Don’t let users do unsigned splices
If a user tries to do a splice without signing their inputs we now provide them with a nice error message and cancel the RPC since that wouldn’t be productive for the user anyway. We also add a helpful message if they do the opposite — try to sign a PSBT where they did not add any inputs. Changelog-Changed: Update prevents users from trying to splice unsigned PSBTs — protecting against potential issues.
This commit is contained in:
parent
3f2b49022e
commit
5818b522f5
2 changed files with 61 additions and 24 deletions
|
@ -1689,37 +1689,58 @@ static bool have_they_signed_inflight(const struct peer *peer,
|
||||||
|
|
||||||
/* This checks if local has signed everything but the funding input */
|
/* This checks if local has signed everything but the funding input */
|
||||||
static bool missing_user_signatures(const struct peer *peer,
|
static bool missing_user_signatures(const struct peer *peer,
|
||||||
const struct inflight *inflight)
|
enum tx_role our_role,
|
||||||
|
struct wally_psbt *psbt)
|
||||||
{
|
{
|
||||||
int sigs_needed;
|
|
||||||
u32 splice_funding_index;
|
u32 splice_funding_index;
|
||||||
const struct witness **outws;
|
if (!psbt) {
|
||||||
enum tx_role our_role = inflight->i_am_initiator
|
status_debug("missing_user_signatures called with NULL psbt");
|
||||||
? TX_INITIATOR : TX_ACCEPTER;
|
|
||||||
|
|
||||||
if (!inflight || !inflight->psbt)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
splice_funding_index = find_channel_funding_input(inflight->psbt,
|
splice_funding_index = find_channel_funding_input(psbt,
|
||||||
&peer->channel->funding);
|
&peer->channel->funding);
|
||||||
sigs_needed = 0;
|
for (u32 i = 0; i < psbt->num_inputs; i++) {
|
||||||
for (u32 i = 0; i < inflight->psbt->num_inputs; i++) {
|
struct wally_psbt_input *in = &psbt->inputs[i];
|
||||||
struct wally_psbt_input *in = &inflight->psbt->inputs[i];
|
|
||||||
u64 in_serial;
|
u64 in_serial;
|
||||||
|
|
||||||
if (!psbt_get_serial_id(&in->unknowns, &in_serial)) {
|
if (!psbt_get_serial_id(&in->unknowns, &in_serial)) {
|
||||||
status_broken("PSBT input %"PRIu32" missing serial_id"
|
status_broken("missing_user_signatures PSBT input %"
|
||||||
" %s", i,
|
PRIu32" missing serial_id %s", i,
|
||||||
fmt_wally_psbt(tmpctx, inflight->psbt));
|
fmt_wally_psbt(tmpctx, psbt));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (in_serial % 2 == our_role && i != splice_funding_index)
|
status_debug("missing_user_signatures[%"PRIu32"], role: %"PRIu64
|
||||||
sigs_needed++;
|
", our_role: %d, in->signatures: %zu"
|
||||||
|
", in->taproot_leaf_signatures.num_items: %zu"
|
||||||
|
", in->final_witness: %p"
|
||||||
|
", splice_funding_index: %"PRIu32
|
||||||
|
", wally_map_get_integer(0x13): %p",
|
||||||
|
i, in_serial % 2, our_role,
|
||||||
|
in->signatures.num_items,
|
||||||
|
in->taproot_leaf_signatures.num_items,
|
||||||
|
in->final_witness, splice_funding_index,
|
||||||
|
wally_map_get_integer(&in->psbt_fields, 0x13));
|
||||||
|
if (in_serial % 2 == our_role && i != splice_funding_index) {
|
||||||
|
status_debug("missing_user_signatures passed role and"
|
||||||
|
" not-funding-index check");
|
||||||
|
if (!in->signatures.num_items
|
||||||
|
&& !in->taproot_leaf_signatures.num_items
|
||||||
|
&& !in->final_witness
|
||||||
|
&& !wally_map_get_integer(&in->psbt_fields, 0x13)) {
|
||||||
|
status_debug("missing_user_signatures true");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
status_debug("missing_user_signatures passed signature"
|
||||||
|
" check");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
status_debug("missing_user_signatures skipping because"
|
||||||
|
" not our role or is splice_funding");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
status_debug("missing_user_signatures false");
|
||||||
outws = psbt_to_witnesses(tmpctx, inflight->psbt,
|
return false;
|
||||||
our_role, splice_funding_index);
|
|
||||||
return tal_count(outws) != sigs_needed;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_tx_abort(struct peer *peer, const u8 *msg)
|
static void check_tx_abort(struct peer *peer, const u8 *msg)
|
||||||
|
@ -4237,6 +4258,16 @@ static void splice_initiator_user_signed(struct peer *peer, const u8 *inmsg)
|
||||||
fmt_bitcoin_txid(tmpctx, &signed_psbt_txid),
|
fmt_bitcoin_txid(tmpctx, &signed_psbt_txid),
|
||||||
fmt_bitcoin_txid(tmpctx, ¤t_psbt_txid));
|
fmt_bitcoin_txid(tmpctx, ¤t_psbt_txid));
|
||||||
|
|
||||||
|
if (missing_user_signatures(peer, TX_INITIATOR, signed_psbt)) {
|
||||||
|
msg = towire_channeld_splice_state_error(NULL, tal_fmt(tmpctx,
|
||||||
|
"The PSBT is"
|
||||||
|
" missing a signature."
|
||||||
|
" Have you signed it"
|
||||||
|
" with `signpsbt`?"));
|
||||||
|
wire_sync_write(MASTER_FD, take(msg));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
tal_free(inflight->psbt);
|
tal_free(inflight->psbt);
|
||||||
inflight->psbt = tal_steal(inflight, signed_psbt);
|
inflight->psbt = tal_steal(inflight, signed_psbt);
|
||||||
|
|
||||||
|
@ -5031,9 +5062,13 @@ static void peer_reconnect(struct peer *peer,
|
||||||
inflight = last_inflight(peer);
|
inflight = last_inflight(peer);
|
||||||
|
|
||||||
if (inflight && (!inflight->last_tx || !inflight->remote_tx_sigs)) {
|
if (inflight && (!inflight->last_tx || !inflight->remote_tx_sigs)) {
|
||||||
if (missing_user_signatures(peer, inflight)) {
|
if (missing_user_signatures(peer,
|
||||||
status_info("Unable to resume splice as user sigs are"
|
inflight->i_am_initiator
|
||||||
" missing.");
|
? TX_INITIATOR
|
||||||
|
: TX_ACCEPTER,
|
||||||
|
inflight->psbt)) {
|
||||||
|
status_info("Unable to resume splice as user sig(s)"
|
||||||
|
" are missing.");
|
||||||
inflight = NULL;
|
inflight = NULL;
|
||||||
} else {
|
} else {
|
||||||
status_info("Reconnecting to peer with pending inflight"
|
status_info("Reconnecting to peer with pending inflight"
|
||||||
|
|
|
@ -813,7 +813,9 @@ static struct command_result *json_signpsbt(struct command *cmd,
|
||||||
|
|
||||||
if (tal_count(utxos) == 0)
|
if (tal_count(utxos) == 0)
|
||||||
return command_fail(cmd, LIGHTNINGD,
|
return command_fail(cmd, LIGHTNINGD,
|
||||||
"No wallet inputs to sign");
|
"No wallet inputs to sign. Are you sure you"
|
||||||
|
" added inputs to this PSBT? If not, then"
|
||||||
|
" there is no need to sign it.");
|
||||||
|
|
||||||
if (command_check_only(cmd))
|
if (command_check_only(cmd))
|
||||||
return command_check_done(cmd);
|
return command_check_done(cmd);
|
||||||
|
|
Loading…
Add table
Reference in a new issue