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->wtx->locktime = nlocktime;
|
||||
tx->wtx->version = 2;
|
||||
tx->output_witscripts = tal_arrz(tx, struct witscript*, output_count);
|
||||
tx->chainparams = chainparams;
|
||||
return tx;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,10 @@
|
|||
|
||||
#define BITCOIN_TX_DEFAULT_SEQUENCE 0xFFFFFFFF
|
||||
|
||||
struct witscript {
|
||||
u8 *ptr;
|
||||
};
|
||||
|
||||
struct bitcoin_txid {
|
||||
struct sha256_double shad;
|
||||
};
|
||||
|
@ -24,6 +28,9 @@ struct bitcoin_tx {
|
|||
struct amount_sat **input_amounts;
|
||||
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 */
|
||||
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],
|
||||
&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));
|
||||
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,
|
||||
const struct htlc *htlc,
|
||||
const struct keyset *keyset)
|
||||
const struct keyset *keyset,
|
||||
struct witscript *o_wscript)
|
||||
{
|
||||
struct ripemd160 ripemd;
|
||||
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,
|
||||
type_to_string(tmpctx, struct amount_sat, &amount),
|
||||
tal_hex(wscript, wscript));
|
||||
o_wscript->ptr = tal_dup_arr(o_wscript, u8, wscript,
|
||||
tal_count(wscript), 0);
|
||||
tal_free(wscript);
|
||||
}
|
||||
|
||||
static void add_received_htlc_out(struct bitcoin_tx *tx, size_t n,
|
||||
const struct htlc *htlc,
|
||||
const struct keyset *keyset)
|
||||
const struct keyset *keyset,
|
||||
struct witscript *o_wscript)
|
||||
{
|
||||
struct ripemd160 ripemd;
|
||||
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,
|
||||
&amount),
|
||||
tal_hex(wscript, wscript));
|
||||
o_wscript->ptr = tal_dup_arr(o_wscript, u8,
|
||||
wscript, tal_count(wscript), 0);
|
||||
tal_free(wscript);
|
||||
}
|
||||
|
||||
|
@ -169,7 +175,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
|||
continue;
|
||||
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
|
||||
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];
|
||||
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
|
||||
n++;
|
||||
|
@ -185,7 +194,10 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
|||
continue;
|
||||
if (trim(htlcs[i], feerate_per_kw, dust_limit, side))
|
||||
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];
|
||||
cltvs[n] = abs_locktime_to_blocks(&htlcs[i]->expiry);
|
||||
n++;
|
||||
|
@ -209,6 +221,11 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
|||
SUPERVERBOSE("# to-local amount %s wscript %s\n",
|
||||
type_to_string(tmpctx, struct amount_sat, &amount),
|
||||
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++;
|
||||
}
|
||||
|
||||
|
@ -252,6 +269,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
|
|||
|
||||
assert(n <= tx->wtx->outputs_allocation_len);
|
||||
tal_resize(htlcmap, n);
|
||||
tal_resize(&(tx->output_witscripts), n);
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
|
|
|
@ -175,6 +175,11 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
|||
int pos = bitcoin_tx_add_output(
|
||||
tx, scriptpubkey_p2wsh(tx, wscript), amount);
|
||||
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++;
|
||||
}
|
||||
|
||||
|
@ -202,6 +207,8 @@ struct bitcoin_tx *initial_commit_tx(const tal_t *ctx,
|
|||
|
||||
assert(n <= tx->wtx->num_outputs);
|
||||
|
||||
tal_resize(&(tx->output_witscripts), n);
|
||||
|
||||
/* BOLT #3:
|
||||
*
|
||||
* 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_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,remote_funding_key,pubkey,
|
||||
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.
|
||||
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 secrets secrets;
|
||||
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,
|
||||
&tx,
|
||||
&remote_funding_pubkey,
|
||||
&funding))
|
||||
&funding,
|
||||
&output_witscripts,
|
||||
&remote_per_commit,
|
||||
&option_static_remotekey))
|
||||
bad_req(conn, c, msg_in);
|
||||
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");
|
||||
if (tx->wtx->num_outputs == 0)
|
||||
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);
|
||||
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,
|
||||
*tx,
|
||||
&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));
|
||||
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,
|
||||
remote_commit,
|
||||
&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));
|
||||
msg = wire_sync_read(tmpctx, HSM_FD);
|
||||
|
|
|
@ -225,6 +225,7 @@ class Type(FieldSet):
|
|||
'exclude_entry',
|
||||
'fee_states',
|
||||
'onionreply',
|
||||
'witscript',
|
||||
]
|
||||
|
||||
# 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;
|
||||
}
|
||||
|
||||
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,
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
towire_bitcoin_blkid(cursor, &chainparams->genesis_blockhash);
|
||||
|
|
|
@ -30,6 +30,7 @@ struct bitcoin_txid;
|
|||
struct preimage;
|
||||
struct ripemd160;
|
||||
struct siphash_seed;
|
||||
struct witscript;
|
||||
|
||||
/* Makes generate-wire.py work */
|
||||
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_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);
|
||||
|
||||
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 bitcoin_tx_output *fromwire_bitcoin_tx_output(const tal_t *ctx,
|
||||
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,
|
||||
const struct chainparams **chainparams);
|
||||
|
|
Loading…
Add table
Reference in a new issue