splice: Add hsmd_check_outpoint and hsmd_lock_outpoint

In general, a validating signer may be under a different operational
environment than the node, and therefore may have a different
source of on-chain data. The signer may therefore temporarily disagree
on whether a funding or splice transaction is locked (buried).

We would like to ensure agreement between the signer and the
node on how to progress a channel's state.

The following message are added to provide a solution:

- `check_outpoint(outpoint) -> bool` - check if the signer agrees that a funding candidate outpoint is buried
- `lock_outpoint(outpoint)` - change the funding/splice state to locked

Link: https://github.com/ElementsProject/lightning/issues/6722
Suggested-by: @devrandom
Co-Developed-by: Ken Sedgwick <ken@bonsai.com>
Changelog-Added: hsmd protocol: Added hsmd_check_outpoint and hsmd_lock_outpoint
Signed-off-by: Vincenzo Palazzo <vincenzopalazzodev@gmail.com>
This commit is contained in:
Ken Sedgwick 2023-09-24 08:51:06 -07:00 committed by Rusty Russell
parent dc4e0a400f
commit 485cabb25e
5 changed files with 67 additions and 0 deletions

View File

@ -18,6 +18,7 @@
* v4 with splicing: 06f21012936f825913af289fa81af1512c9ada1cb97c611698975a8fd287edbb
* v4 with capabilities called permissions: 7c5bf8ec7cf30302740db85260a9d1ac2c5b0323a2376c28df6b611831f91655
* v4 with renaming of channel_ready to setup_channel: 60b92a0930b631cc77df564cb9235e6cb220f4337a2bb00e5153145e0bf8c80e
* v4 with buried outpoint check: f44fae666895cab0347b3de7c245267c71cc7de834827b83e286e86318c08aec
*/
#define HSM_MIN_VERSION 3
#define HSM_MAX_VERSION 4

View File

@ -645,6 +645,8 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
/* fall thru */
case WIRE_HSMD_NEW_CHANNEL:
case WIRE_HSMD_SETUP_CHANNEL:
case WIRE_HSMD_CHECK_OUTPOINT:
case WIRE_HSMD_LOCK_OUTPOINT:
case WIRE_HSMD_SIGN_COMMITMENT_TX:
case WIRE_HSMD_VALIDATE_COMMITMENT_TX:
case WIRE_HSMD_VALIDATE_REVOCATION:
@ -690,6 +692,8 @@ static struct io_plan *handle_client(struct io_conn *conn, struct client *c)
case WIRE_HSMD_CLIENT_HSMFD_REPLY:
case WIRE_HSMD_NEW_CHANNEL_REPLY:
case WIRE_HSMD_SETUP_CHANNEL_REPLY:
case WIRE_HSMD_CHECK_OUTPOINT_REPLY:
case WIRE_HSMD_LOCK_OUTPOINT_REPLY:
case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REPLY:
case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY:
case WIRE_HSMD_SIGN_INVOICE_REPLY:

View File

@ -89,6 +89,22 @@ msgdata,hsmd_setup_channel,channel_type,channel_type,
# No value returned.,
msgtype,hsmd_setup_channel_reply,131
# check if the signer agrees that a funding candidate outpoint is buried
msgtype,hsmd_check_outpoint,32
msgdata,hsmd_check_outpoint,funding_txid,bitcoin_txid,
msgdata,hsmd_check_outpoint,funding_txout,u16,
msgtype,hsmd_check_outpoint_reply,132
msgdata,hsmd_check_outpoint_reply,is_buried,bool,
# change the funding/splice state to locked
msgtype,hsmd_lock_outpoint,37
msgdata,hsmd_lock_outpoint,funding_txid,bitcoin_txid,
msgdata,hsmd_lock_outpoint,funding_txout,u16,
# No value returned.
msgtype,hsmd_lock_outpoint_reply,137
# Return signature for a funding tx.
#include <common/utxo.h>

1 # Clients should not give a bad request but not the HSM's decision to crash.
89 #include <bitcoin/psbt.h> msgdata,hsmd_lock_outpoint,funding_txout,u16,
90 msgtype,hsmd_sign_withdrawal,7 # No value returned.
91 msgdata,hsmd_sign_withdrawal,num_inputs,u16, msgtype,hsmd_lock_outpoint_reply,137
92 # Return signature for a funding tx.
93 #include <common/utxo.h>
94 # Master asks the HSM to sign a node_announcement
95 msgtype,hsmd_node_announcement_sig_req,6
96 msgdata,hsmd_node_announcement_sig_req,annlen,u16,
97 msgdata,hsmd_node_announcement_sig_req,announcement,u8,annlen
98 msgtype,hsmd_node_announcement_sig_reply,106
99 msgdata,hsmd_node_announcement_sig_reply,signature,secp256k1_ecdsa_signature,
100 # Sign a withdrawal request
101 #include <bitcoin/psbt.h>
102 msgtype,hsmd_sign_withdrawal,7
103 msgdata,hsmd_sign_withdrawal,num_inputs,u16,
104 msgdata,hsmd_sign_withdrawal,inputs,utxo,num_inputs
105 msgdata,hsmd_sign_withdrawal,psbt,wally_psbt,
106 msgtype,hsmd_sign_withdrawal_reply,107
107 msgdata,hsmd_sign_withdrawal_reply,psbt,wally_psbt,
108 msgdata,hsmd_sign_withdrawal,inputs,utxo,num_inputs # Sign an invoice
109 msgdata,hsmd_sign_withdrawal,psbt,wally_psbt, msgtype,hsmd_sign_invoice,8
110 msgtype,hsmd_sign_withdrawal_reply,107 msgdata,hsmd_sign_invoice,len,u16,

View File

@ -112,6 +112,10 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
case WIRE_HSMD_SIGN_OPTION_WILL_FUND_OFFER:
return (client->capabilities & HSM_PERM_SIGN_WILL_FUND_OFFER) != 0;
case WIRE_HSMD_CHECK_OUTPOINT:
case WIRE_HSMD_LOCK_OUTPOINT:
return (client->capabilities & HSM_PERM_LOCK_OUTPOINT) != 0;
case WIRE_HSMD_INIT:
case WIRE_HSMD_NEW_CHANNEL:
case WIRE_HSMD_CLIENT_HSMFD:
@ -144,6 +148,8 @@ bool hsmd_check_client_capabilities(struct hsmd_client *client,
case WIRE_HSMD_CLIENT_HSMFD_REPLY:
case WIRE_HSMD_NEW_CHANNEL_REPLY:
case WIRE_HSMD_SETUP_CHANNEL_REPLY:
case WIRE_HSMD_CHECK_OUTPOINT_REPLY:
case WIRE_HSMD_LOCK_OUTPOINT_REPLY:
case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REPLY:
case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY:
case WIRE_HSMD_SIGN_INVOICE_REPLY:
@ -376,6 +382,38 @@ static u8 *handle_setup_channel(struct hsmd_client *c, const u8 *msg_in)
return towire_hsmd_setup_channel_reply(NULL);
}
/* ~This stub implementation is overriden by fully validating signers
* to ensure they are caught up when outpoints are freshly buried */
static u8 *handle_check_outpoint(struct hsmd_client *c, const u8 *msg_in)
{
struct bitcoin_txid funding_txid;
u16 funding_txout;
bool is_buried;
if (!fromwire_hsmd_check_outpoint(msg_in, &funding_txid, &funding_txout))
return hsmd_status_malformed_request(c, msg_in);
/* This stub always approves */
is_buried = true;
return towire_hsmd_check_outpoint_reply(NULL, is_buried);
}
/* ~This stub implementation is overriden by fully validating signers to
* change their funding/splice state to locked */
static u8 *handle_lock_outpoint(struct hsmd_client *c, const u8 *msg_in)
{
struct bitcoin_txid funding_txid;
u16 funding_txout;
if (!fromwire_hsmd_lock_outpoint(msg_in, &funding_txid, &funding_txout))
return hsmd_status_malformed_request(c, msg_in);
/* Stub implementation */
return towire_hsmd_lock_outpoint_reply(NULL);
}
/*~ For almost every wallet tx we use the BIP32 seed, but not for onchain
* unilateral closes from a peer: they (may) have an output to us using a
* public key based on the channel basepoints. It's a bit spammy to spend
@ -1903,6 +1941,10 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
return handle_new_channel(client, msg);
case WIRE_HSMD_SETUP_CHANNEL:
return handle_setup_channel(client, msg);
case WIRE_HSMD_CHECK_OUTPOINT:
return handle_check_outpoint(client, msg);
case WIRE_HSMD_LOCK_OUTPOINT:
return handle_lock_outpoint(client, msg);
case WIRE_HSMD_GET_OUTPUT_SCRIPTPUBKEY:
return handle_get_output_scriptpubkey(client, msg);
case WIRE_HSMD_CHECK_FUTURE_SECRET:
@ -1980,6 +2022,8 @@ u8 *hsmd_handle_client_message(const tal_t *ctx, struct hsmd_client *client,
case WIRE_HSMD_CLIENT_HSMFD_REPLY:
case WIRE_HSMD_NEW_CHANNEL_REPLY:
case WIRE_HSMD_SETUP_CHANNEL_REPLY:
case WIRE_HSMD_CHECK_OUTPOINT_REPLY:
case WIRE_HSMD_LOCK_OUTPOINT_REPLY:
case WIRE_HSMD_NODE_ANNOUNCEMENT_SIG_REPLY:
case WIRE_HSMD_SIGN_WITHDRAWAL_REPLY:
case WIRE_HSMD_SIGN_INVOICE_REPLY:
@ -2022,6 +2066,7 @@ u8 *hsmd_init(struct secret hsm_secret,
WIRE_HSMD_SIGN_ANCHORSPEND,
WIRE_HSMD_SIGN_HTLC_TX_MINGLE,
WIRE_HSMD_SIGN_SPLICE_TX,
WIRE_HSMD_CHECK_OUTPOINT,
};
/*~ Don't swap this. */

View File

@ -10,6 +10,7 @@
#define HSM_PERM_SIGN_CLOSING_TX 32
#define HSM_PERM_SIGN_WILL_FUND_OFFER 64
#define HSM_PERM_SIGN_SPLICE_TX 128
#define HSM_PERM_LOCK_OUTPOINT 256
#define HSM_PERM_MASTER 1024
#endif /* LIGHTNING_HSMD_PERMISSIONS_H */