Skip to content

Commit 5818b52

Browse files
ddustinendothermicdev
authored andcommitted
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.
1 parent 3f2b490 commit 5818b52

File tree

2 files changed

+61
-24
lines changed

2 files changed

+61
-24
lines changed

channeld/channeld.c

Lines changed: 58 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1689,37 +1689,58 @@ static bool have_they_signed_inflight(const struct peer *peer,
16891689

16901690
/* This checks if local has signed everything but the funding input */
16911691
static bool missing_user_signatures(const struct peer *peer,
1692-
const struct inflight *inflight)
1692+
enum tx_role our_role,
1693+
struct wally_psbt *psbt)
16931694
{
1694-
int sigs_needed;
16951695
u32 splice_funding_index;
1696-
const struct witness **outws;
1697-
enum tx_role our_role = inflight->i_am_initiator
1698-
? TX_INITIATOR : TX_ACCEPTER;
1699-
1700-
if (!inflight || !inflight->psbt)
1696+
if (!psbt) {
1697+
status_debug("missing_user_signatures called with NULL psbt");
17011698
return false;
1699+
}
17021700

1703-
splice_funding_index = find_channel_funding_input(inflight->psbt,
1701+
splice_funding_index = find_channel_funding_input(psbt,
17041702
&peer->channel->funding);
1705-
sigs_needed = 0;
1706-
for (u32 i = 0; i < inflight->psbt->num_inputs; i++) {
1707-
struct wally_psbt_input *in = &inflight->psbt->inputs[i];
1703+
for (u32 i = 0; i < psbt->num_inputs; i++) {
1704+
struct wally_psbt_input *in = &psbt->inputs[i];
17081705
u64 in_serial;
17091706

17101707
if (!psbt_get_serial_id(&in->unknowns, &in_serial)) {
1711-
status_broken("PSBT input %"PRIu32" missing serial_id"
1712-
" %s", i,
1713-
fmt_wally_psbt(tmpctx, inflight->psbt));
1708+
status_broken("missing_user_signatures PSBT input %"
1709+
PRIu32" missing serial_id %s", i,
1710+
fmt_wally_psbt(tmpctx, psbt));
17141711
return true;
17151712
}
1716-
if (in_serial % 2 == our_role && i != splice_funding_index)
1717-
sigs_needed++;
1713+
status_debug("missing_user_signatures[%"PRIu32"], role: %"PRIu64
1714+
", our_role: %d, in->signatures: %zu"
1715+
", in->taproot_leaf_signatures.num_items: %zu"
1716+
", in->final_witness: %p"
1717+
", splice_funding_index: %"PRIu32
1718+
", wally_map_get_integer(0x13): %p",
1719+
i, in_serial % 2, our_role,
1720+
in->signatures.num_items,
1721+
in->taproot_leaf_signatures.num_items,
1722+
in->final_witness, splice_funding_index,
1723+
wally_map_get_integer(&in->psbt_fields, 0x13));
1724+
if (in_serial % 2 == our_role && i != splice_funding_index) {
1725+
status_debug("missing_user_signatures passed role and"
1726+
" not-funding-index check");
1727+
if (!in->signatures.num_items
1728+
&& !in->taproot_leaf_signatures.num_items
1729+
&& !in->final_witness
1730+
&& !wally_map_get_integer(&in->psbt_fields, 0x13)) {
1731+
status_debug("missing_user_signatures true");
1732+
return true;
1733+
}
1734+
status_debug("missing_user_signatures passed signature"
1735+
" check");
1736+
}
1737+
else {
1738+
status_debug("missing_user_signatures skipping because"
1739+
" not our role or is splice_funding");
1740+
}
17181741
}
1719-
1720-
outws = psbt_to_witnesses(tmpctx, inflight->psbt,
1721-
our_role, splice_funding_index);
1722-
return tal_count(outws) != sigs_needed;
1742+
status_debug("missing_user_signatures false");
1743+
return false;
17231744
}
17241745

17251746
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)
42374258
fmt_bitcoin_txid(tmpctx, &signed_psbt_txid),
42384259
fmt_bitcoin_txid(tmpctx, &current_psbt_txid));
42394260

4261+
if (missing_user_signatures(peer, TX_INITIATOR, signed_psbt)) {
4262+
msg = towire_channeld_splice_state_error(NULL, tal_fmt(tmpctx,
4263+
"The PSBT is"
4264+
" missing a signature."
4265+
" Have you signed it"
4266+
" with `signpsbt`?"));
4267+
wire_sync_write(MASTER_FD, take(msg));
4268+
return;
4269+
}
4270+
42404271
tal_free(inflight->psbt);
42414272
inflight->psbt = tal_steal(inflight, signed_psbt);
42424273

@@ -5031,9 +5062,13 @@ static void peer_reconnect(struct peer *peer,
50315062
inflight = last_inflight(peer);
50325063

50335064
if (inflight && (!inflight->last_tx || !inflight->remote_tx_sigs)) {
5034-
if (missing_user_signatures(peer, inflight)) {
5035-
status_info("Unable to resume splice as user sigs are"
5036-
" missing.");
5065+
if (missing_user_signatures(peer,
5066+
inflight->i_am_initiator
5067+
? TX_INITIATOR
5068+
: TX_ACCEPTER,
5069+
inflight->psbt)) {
5070+
status_info("Unable to resume splice as user sig(s)"
5071+
" are missing.");
50375072
inflight = NULL;
50385073
} else {
50395074
status_info("Reconnecting to peer with pending inflight"

wallet/walletrpc.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,9 @@ static struct command_result *json_signpsbt(struct command *cmd,
813813

814814
if (tal_count(utxos) == 0)
815815
return command_fail(cmd, LIGHTNINGD,
816-
"No wallet inputs to sign");
816+
"No wallet inputs to sign. Are you sure you"
817+
" added inputs to this PSBT? If not, then"
818+
" there is no need to sign it.");
817819

818820
if (command_check_only(cmd))
819821
return command_check_done(cmd);

0 commit comments

Comments
 (0)