mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
hsmd: Added fields to hsm_sign_remote_commitment_tx to allow complete validation.
Changelog-Added: hsmd: Added fields to hsm_sign_remote_commitment_tx to allow complete validation by signing daemon.
This commit is contained in:
parent
149620ee0f
commit
5c8f881a75
13 changed files with 97 additions and 8 deletions
|
@ -399,6 +399,7 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx,
|
||||||
tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count);
|
tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count);
|
||||||
tx->wtx->locktime = nlocktime;
|
tx->wtx->locktime = nlocktime;
|
||||||
tx->wtx->version = 2;
|
tx->wtx->version = 2;
|
||||||
|
tx->output_witscripts = tal_arrz(tx, struct witscript*, output_count);
|
||||||
tx->chainparams = chainparams;
|
tx->chainparams = chainparams;
|
||||||
return tx;
|
return tx;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
|
|
||||||
#define BITCOIN_TX_DEFAULT_SEQUENCE 0xFFFFFFFF
|
#define BITCOIN_TX_DEFAULT_SEQUENCE 0xFFFFFFFF
|
||||||
|
|
||||||
|
struct witscript {
|
||||||
|
u8 *ptr;
|
||||||
|
};
|
||||||
|
|
||||||
struct bitcoin_txid {
|
struct bitcoin_txid {
|
||||||
struct sha256_double shad;
|
struct sha256_double shad;
|
||||||
};
|
};
|
||||||
|
@ -24,6 +28,9 @@ struct bitcoin_tx {
|
||||||
struct amount_sat **input_amounts;
|
struct amount_sat **input_amounts;
|
||||||
struct wally_tx *wtx;
|
struct wally_tx *wtx;
|
||||||
|
|
||||||
|
/* Need the output wscripts in the HSM to validate transaction */
|
||||||
|
struct witscript **output_witscripts;
|
||||||
|
|
||||||
/* Keep a reference to the ruleset we have to abide by */
|
/* Keep a reference to the ruleset we have to abide by */
|
||||||
const struct chainparams *chainparams;
|
const struct chainparams *chainparams;
|
||||||
};
|
};
|
||||||
|
|
|
@ -995,7 +995,10 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx,
|
||||||
|
|
||||||
msg = towire_hsm_sign_remote_commitment_tx(NULL, txs[0],
|
msg = towire_hsm_sign_remote_commitment_tx(NULL, txs[0],
|
||||||
&peer->channel->funding_pubkey[REMOTE],
|
&peer->channel->funding_pubkey[REMOTE],
|
||||||
*txs[0]->input_amounts[0]);
|
*txs[0]->input_amounts[0],
|
||||||
|
(const struct witscript **) txs[0]->output_witscripts,
|
||||||
|
&peer->remote_per_commit,
|
||||||
|
peer->channel->option_static_remotekey);
|
||||||
|
|
||||||
msg = hsm_req(tmpctx, take(msg));
|
msg = hsm_req(tmpctx, take(msg));
|
||||||
if (!fromwire_hsm_sign_tx_reply(msg, commit_sig))
|
if (!fromwire_hsm_sign_tx_reply(msg, commit_sig))
|
||||||
|
|
|
@ -36,7 +36,8 @@ size_t commit_tx_num_untrimmed(const struct htlc **htlcs,
|
||||||
|
|
||||||
static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
|
static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
|
||||||
const struct htlc *htlc,
|
const struct htlc *htlc,
|
||||||
const struct keyset *keyset)
|
const struct keyset *keyset,
|
||||||
|
struct witscript *o_wscript)
|
||||||
{
|
{
|
||||||
struct ripemd160 ripemd;
|
struct ripemd160 ripemd;
|
||||||
u8 *wscript, *p2wsh;
|
u8 *wscript, *p2wsh;
|
||||||
|
@ -49,12 +50,15 @@ static void add_offered_htlc_out(struct bitcoin_tx *tx, size_t n,
|
||||||
SUPERVERBOSE("# HTLC %" PRIu64 " offered %s wscript %s\n", htlc->id,
|
SUPERVERBOSE("# HTLC %" PRIu64 " offered %s wscript %s\n", htlc->id,
|
||||||
type_to_string(tmpctx, struct amount_sat, &amount),
|
type_to_string(tmpctx, struct amount_sat, &amount),
|
||||||
tal_hex(wscript, wscript));
|
tal_hex(wscript, wscript));
|
||||||
|
o_wscript->ptr = tal_dup_arr(o_wscript, u8, wscript,
|
||||||
|
tal_count(wscript), 0);
|
||||||
tal_free(wscript);
|
tal_free(wscript);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
|
static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
|
||||||
const struct htlc *htlc,
|
const struct htlc *htlc,
|
||||||
const struct keyset *keyset)
|
const struct keyset *keyset,
|
||||||
|
struct witscript *o_wscript)
|
||||||
{
|
{
|
||||||
struct ripemd160 ripemd;
|
struct ripemd160 ripemd;
|
||||||
u8 *wscript, *p2wsh;
|
u8 *wscript, *p2wsh;
|
||||||
|
@ -72,6 +76,8 @@ static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
|
||||||
type_to_string(tmpctx, struct amount_sat,
|
type_to_string(tmpctx, struct amount_sat,
|
||||||
&amount),
|
&amount),
|
||||||
tal_hex(wscript, wscript));
|
tal_hex(wscript, wscript));
|
||||||
|
o_wscript->ptr = tal_dup_arr(o_wscript, u8,
|
||||||
|
wscript, tal_count(wscript), 0);
|
||||||
tal_free(wscript);
|
tal_free(wscript);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +175,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
||||||
continue;
|
continue;
|
||||||
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
|
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
|
||||||
continue;
|
continue;
|
||||||
add_offered_htlc_out(tx, n, htlcs[i], keyset);
|
tx->output_witscripts[n] =
|
||||||
|
tal(tx->output_witscripts, struct witscript);
|
||||||
|
add_offered_htlc_out(tx, n, htlcs[i],
|
||||||
|
keyset, tx->output_witscripts[n]);
|
||||||
(*htlcmap)[n] = htlcs[i];
|
(*htlcmap)[n] = htlcs[i];
|
||||||
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
|
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
|
||||||
n++;
|
n++;
|
||||||
|
@ -185,7 +194,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
||||||
continue;
|
continue;
|
||||||
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
|
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
|
||||||
continue;
|
continue;
|
||||||
add_received_htlc_out(tx, n, htlcs[i], keyset);
|
tx->output_witscripts[n] =
|
||||||
|
tal(tx->output_witscripts, struct witscript);
|
||||||
|
add_received_htlc_out(tx, n, htlcs[i], keyset,
|
||||||
|
tx->output_witscripts[n]);
|
||||||
(*htlcmap)[n] = htlcs[i];
|
(*htlcmap)[n] = htlcs[i];
|
||||||
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
|
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
|
||||||
n++;
|
n++;
|
||||||
|
@ -209,6 +221,11 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
||||||
SUPERVERBOSE("# to-local amount %s wscript %s\n",
|
SUPERVERBOSE("# to-local amount %s wscript %s\n",
|
||||||
type_to_string(tmpctx, struct amount_sat, &amount),
|
type_to_string(tmpctx, struct amount_sat, &amount),
|
||||||
tal_hex(tmpctx, wscript));
|
tal_hex(tmpctx, wscript));
|
||||||
|
tx->output_witscripts[n] =
|
||||||
|
tal(tx->output_witscripts, struct witscript);
|
||||||
|
tx->output_witscripts[n]->ptr =
|
||||||
|
tal_dup_arr(tx->output_witscripts[n], u8,
|
||||||
|
wscript, tal_count(wscript), 0);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -252,6 +269,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
||||||
|
|
||||||
assert(n <= tx->wtx->outputs_allocation_len);
|
assert(n <= tx->wtx->outputs_allocation_len);
|
||||||
tal_resize(htlcmap, n);
|
tal_resize(htlcmap, n);
|
||||||
|
tal_resize(&(tx->output_witscripts), n);
|
||||||
|
|
||||||
/* BOLT #3:
|
/* BOLT #3:
|
||||||
*
|
*
|
||||||
|
|
|
@ -175,6 +175,11 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
||||||
int pos = bitcoin_tx_add_output(
|
int pos = bitcoin_tx_add_output(
|
||||||
tx, scriptpubkey_p2wsh(tx, wscript), amount);
|
tx, scriptpubkey_p2wsh(tx, wscript), amount);
|
||||||
assert(pos == n);
|
assert(pos == n);
|
||||||
|
tx->output_witscripts[n] =
|
||||||
|
tal(tx->output_witscripts, struct witscript);
|
||||||
|
tx->output_witscripts[n]->ptr =
|
||||||
|
tal_dup_arr(tx->output_witscripts[n], u8,
|
||||||
|
wscript, tal_count(wscript), 0);
|
||||||
n++;
|
n++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,6 +207,8 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
||||||
|
|
||||||
assert(n <= tx->wtx->num_outputs);
|
assert(n <= tx->wtx->num_outputs);
|
||||||
|
|
||||||
|
tal_resize(&(tx->output_witscripts), n);
|
||||||
|
|
||||||
/* BOLT #3:
|
/* BOLT #3:
|
||||||
*
|
*
|
||||||
* 7. Sort the outputs into [BIP 69+CLTV
|
* 7. Sort the outputs into [BIP 69+CLTV
|
||||||
|
|
|
@ -174,5 +174,12 @@ void permute_outputs(struct bitcoin_tx *tx, u32 *cltvs, const void **map)
|
||||||
|
|
||||||
/* Swap best into first place. */
|
/* Swap best into first place. */
|
||||||
swap_wally_outputs(tx->wtx->outputs, map, cltvs, i, best_pos);
|
swap_wally_outputs(tx->wtx->outputs, map, cltvs, i, best_pos);
|
||||||
|
|
||||||
|
/* If output_witscripts are present, swap them to match. */
|
||||||
|
if (tx->output_witscripts) {
|
||||||
|
struct witscript *tmp = tx->output_witscripts[i];
|
||||||
|
tx->output_witscripts[i] = tx->output_witscripts[best_pos];
|
||||||
|
tx->output_witscripts[best_pos] = tmp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,10 @@ msgtype,hsm_sign_remote_commitment_tx,19
|
||||||
msgdata,hsm_sign_remote_commitment_tx,tx,bitcoin_tx,
|
msgdata,hsm_sign_remote_commitment_tx,tx,bitcoin_tx,
|
||||||
msgdata,hsm_sign_remote_commitment_tx,remote_funding_key,pubkey,
|
msgdata,hsm_sign_remote_commitment_tx,remote_funding_key,pubkey,
|
||||||
msgdata,hsm_sign_remote_commitment_tx,funding_amount,amount_sat,
|
msgdata,hsm_sign_remote_commitment_tx,funding_amount,amount_sat,
|
||||||
|
msgdata,hsm_sign_remote_commitment_tx,num_witscripts,u16,
|
||||||
|
msgdata,hsm_sign_remote_commitment_tx,output_witscripts,witscript,num_witscripts
|
||||||
|
msgdata,hsm_sign_remote_commitment_tx,remote_per_commit,pubkey,
|
||||||
|
msgdata,hsm_sign_remote_commitment_tx,option_static_remotekey,bool,
|
||||||
|
|
||||||
# channeld asks HSM to sign remote HTLC tx.
|
# channeld asks HSM to sign remote HTLC tx.
|
||||||
msgtype,hsm_sign_remote_htlc_tx,20
|
msgtype,hsm_sign_remote_htlc_tx,20
|
||||||
|
|
|
10
hsmd/hsmd.c
10
hsmd/hsmd.c
|
@ -996,11 +996,17 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
|
||||||
struct bitcoin_signature sig;
|
struct bitcoin_signature sig;
|
||||||
struct secrets secrets;
|
struct secrets secrets;
|
||||||
const u8 *funding_wscript;
|
const u8 *funding_wscript;
|
||||||
|
struct witscript **output_witscripts;
|
||||||
|
struct pubkey remote_per_commit;
|
||||||
|
bool option_static_remotekey;
|
||||||
|
|
||||||
if (!fromwire_hsm_sign_remote_commitment_tx(tmpctx, msg_in,
|
if (!fromwire_hsm_sign_remote_commitment_tx(tmpctx, msg_in,
|
||||||
&tx,
|
&tx,
|
||||||
&remote_funding_pubkey,
|
&remote_funding_pubkey,
|
||||||
&funding))
|
&funding,
|
||||||
|
&output_witscripts,
|
||||||
|
&remote_per_commit,
|
||||||
|
&option_static_remotekey))
|
||||||
bad_req(conn, c, msg_in);
|
bad_req(conn, c, msg_in);
|
||||||
tx->chainparams = c->chainparams;
|
tx->chainparams = c->chainparams;
|
||||||
|
|
||||||
|
@ -1009,6 +1015,8 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
|
||||||
return bad_req_fmt(conn, c, msg_in, "tx must have 1 input");
|
return bad_req_fmt(conn, c, msg_in, "tx must have 1 input");
|
||||||
if (tx->wtx->num_outputs == 0)
|
if (tx->wtx->num_outputs == 0)
|
||||||
return bad_req_fmt(conn, c, msg_in, "tx must have > 0 outputs");
|
return bad_req_fmt(conn, c, msg_in, "tx must have > 0 outputs");
|
||||||
|
if (tal_count(output_witscripts) != tx->wtx->num_outputs)
|
||||||
|
return bad_req_fmt(conn, c, msg_in, "tx must have matching witscripts");
|
||||||
|
|
||||||
get_channel_seed(&c->id, c->dbid, &channel_seed);
|
get_channel_seed(&c->id, c->dbid, &channel_seed);
|
||||||
derive_basepoints(&channel_seed,
|
derive_basepoints(&channel_seed,
|
||||||
|
|
|
@ -719,7 +719,10 @@ static bool funder_finalize_channel_setup(struct state *state,
|
||||||
msg = towire_hsm_sign_remote_commitment_tx(NULL,
|
msg = towire_hsm_sign_remote_commitment_tx(NULL,
|
||||||
*tx,
|
*tx,
|
||||||
&state->channel->funding_pubkey[REMOTE],
|
&state->channel->funding_pubkey[REMOTE],
|
||||||
state->channel->funding);
|
state->channel->funding,
|
||||||
|
(const struct witscript **) (*tx)->output_witscripts,
|
||||||
|
&state->first_per_commitment_point[REMOTE],
|
||||||
|
state->channel->option_static_remotekey);
|
||||||
|
|
||||||
wire_sync_write(HSM_FD, take(msg));
|
wire_sync_write(HSM_FD, take(msg));
|
||||||
msg = wire_sync_read(tmpctx, HSM_FD);
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
||||||
|
@ -1234,7 +1237,10 @@ static u8 *fundee_channel(struct state *state, const u8 *open_channel_msg)
|
||||||
msg = towire_hsm_sign_remote_commitment_tx(NULL,
|
msg = towire_hsm_sign_remote_commitment_tx(NULL,
|
||||||
remote_commit,
|
remote_commit,
|
||||||
&state->channel->funding_pubkey[REMOTE],
|
&state->channel->funding_pubkey[REMOTE],
|
||||||
state->channel->funding);
|
state->channel->funding,
|
||||||
|
(const struct witscript **) remote_commit->output_witscripts,
|
||||||
|
&state->first_per_commitment_point[REMOTE],
|
||||||
|
state->channel->option_static_remotekey);
|
||||||
|
|
||||||
wire_sync_write(HSM_FD, take(msg));
|
wire_sync_write(HSM_FD, take(msg));
|
||||||
msg = wire_sync_read(tmpctx, HSM_FD);
|
msg = wire_sync_read(tmpctx, HSM_FD);
|
||||||
|
|
|
@ -225,6 +225,7 @@ class Type(FieldSet):
|
||||||
'exclude_entry',
|
'exclude_entry',
|
||||||
'fee_states',
|
'fee_states',
|
||||||
'onionreply',
|
'onionreply',
|
||||||
|
'witscript',
|
||||||
]
|
]
|
||||||
|
|
||||||
# Some BOLT types are re-typed based on their field name
|
# Some BOLT types are re-typed based on their field name
|
||||||
|
|
|
@ -403,6 +403,18 @@ struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx,
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct witscript *fromwire_witscript(const tal_t *ctx, const u8 **cursor, size_t *max)
|
||||||
|
{
|
||||||
|
struct witscript *retval;
|
||||||
|
u16 len = fromwire_u16(cursor, max);
|
||||||
|
if (!len)
|
||||||
|
return NULL;
|
||||||
|
retval = tal(ctx, struct witscript);
|
||||||
|
retval->ptr = tal_arr(retval, u8, len);
|
||||||
|
fromwire_u8_array(cursor, max, retval->ptr, len);
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
void fromwire_chainparams(const u8 **cursor, size_t *max,
|
void fromwire_chainparams(const u8 **cursor, size_t *max,
|
||||||
const struct chainparams **chainparams)
|
const struct chainparams **chainparams)
|
||||||
{
|
{
|
||||||
|
|
|
@ -263,6 +263,17 @@ void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output)
|
||||||
towire_u8_array(pptr, output->script, tal_count(output->script));
|
towire_u8_array(pptr, output->script, tal_count(output->script));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void towire_witscript(u8 **pptr, const struct witscript *script)
|
||||||
|
{
|
||||||
|
if (script == NULL) {
|
||||||
|
towire_u16(pptr, 0);
|
||||||
|
} else {
|
||||||
|
assert(script->ptr != NULL);
|
||||||
|
towire_u16(pptr, tal_count(script->ptr));
|
||||||
|
towire_u8_array(pptr, script->ptr, tal_count(script->ptr));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void towire_chainparams(u8 **cursor, const struct chainparams *chainparams)
|
void towire_chainparams(u8 **cursor, const struct chainparams *chainparams)
|
||||||
{
|
{
|
||||||
towire_bitcoin_blkid(cursor, &chainparams->genesis_blockhash);
|
towire_bitcoin_blkid(cursor, &chainparams->genesis_blockhash);
|
||||||
|
|
|
@ -30,6 +30,7 @@ struct bitcoin_txid;
|
||||||
struct preimage;
|
struct preimage;
|
||||||
struct ripemd160;
|
struct ripemd160;
|
||||||
struct siphash_seed;
|
struct siphash_seed;
|
||||||
|
struct witscript;
|
||||||
|
|
||||||
/* Makes generate-wire.py work */
|
/* Makes generate-wire.py work */
|
||||||
typedef char wirestring;
|
typedef char wirestring;
|
||||||
|
@ -91,6 +92,7 @@ void towire_siphash_seed(u8 **cursor, const struct siphash_seed *seed);
|
||||||
|
|
||||||
void towire_bip32_key_version(u8 **cursor, const struct bip32_key_version *version);
|
void towire_bip32_key_version(u8 **cursor, const struct bip32_key_version *version);
|
||||||
void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output);
|
void towire_bitcoin_tx_output(u8 **pptr, const struct bitcoin_tx_output *output);
|
||||||
|
void towire_witscript(u8 **pptr, const struct witscript *script);
|
||||||
void towire_chainparams(u8 **cursor, const struct chainparams *chainparams);
|
void towire_chainparams(u8 **cursor, const struct chainparams *chainparams);
|
||||||
|
|
||||||
const u8 *fromwire(const u8 **cursor, size_t *max, void *copy, size_t n);
|
const u8 *fromwire(const u8 **cursor, size_t *max, void *copy, size_t n);
|
||||||
|
@ -145,6 +147,8 @@ void fromwire_bip32_key_version(const u8 **cursor, size_t *max,
|
||||||
struct bip32_key_version *version);
|
struct bip32_key_version *version);
|
||||||
struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx,
|
struct bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx,
|
||||||
const u8 **cursor, size_t *max);
|
const u8 **cursor, size_t *max);
|
||||||
|
struct witscript *fromwire_witscript(const tal_t *ctx,
|
||||||
|
const u8 **cursor, size_t *max);
|
||||||
|
|
||||||
void fromwire_chainparams(const u8 **cursor, size_t *max,
|
void fromwire_chainparams(const u8 **cursor, size_t *max,
|
||||||
const struct chainparams **chainparams);
|
const struct chainparams **chainparams);
|
||||||
|
|
Loading…
Add table
Reference in a new issue