mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-10 01:24:30 +01:00
hsm: Generate fully signed funding transaction in the HSM
Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
23
hsmd/hsm.c
23
hsmd/hsm.c
@@ -545,10 +545,10 @@ static void sign_funding_tx(struct daemon_conn *master, const u8 *msg)
|
||||
const struct utxo **utxomap;
|
||||
struct bitcoin_tx *tx;
|
||||
u8 *wscript;
|
||||
secp256k1_ecdsa_signature *sig;
|
||||
u16 outnum;
|
||||
size_t i;
|
||||
struct pubkey changekey;
|
||||
u8 **scriptSigs;
|
||||
|
||||
/* FIXME: Check fee is "reasonable" */
|
||||
if (!fromwire_hsm_sign_funding(tmpctx, msg, NULL,
|
||||
@@ -567,13 +567,13 @@ static void sign_funding_tx(struct daemon_conn *master, const u8 *msg)
|
||||
change_out, &changekey,
|
||||
NULL);
|
||||
|
||||
/* Now generate signatures. */
|
||||
sig = tal_arr(tmpctx, secp256k1_ecdsa_signature, tal_count(inputs));
|
||||
scriptSigs = tal_arr(tmpctx, u8*, tal_count(inputs));
|
||||
for (i = 0; i < tal_count(inputs); i++) {
|
||||
struct pubkey inkey;
|
||||
struct privkey inprivkey;
|
||||
const struct utxo *in = utxomap[i];
|
||||
u8 *subscript;
|
||||
secp256k1_ecdsa_signature sig;
|
||||
|
||||
bitcoin_keypair(&inprivkey, &inkey, in->keyindex);
|
||||
if (in->is_p2sh)
|
||||
@@ -582,12 +582,23 @@ static void sign_funding_tx(struct daemon_conn *master, const u8 *msg)
|
||||
subscript = NULL;
|
||||
wscript = p2wpkh_scriptcode(tmpctx, &inkey);
|
||||
|
||||
sign_tx_input(tx, i, subscript, wscript,
|
||||
&inprivkey, &inkey, &sig[i]);
|
||||
sign_tx_input(tx, i, subscript, wscript, &inprivkey, &inkey,
|
||||
&sig);
|
||||
|
||||
tx->input[i].witness = bitcoin_witness_p2wpkh(tx, &sig, &inkey);
|
||||
|
||||
if (inputs[i].is_p2sh)
|
||||
scriptSigs[i] = bitcoin_scriptsig_p2sh_p2wpkh(tx, &inkey);
|
||||
else
|
||||
scriptSigs[i] = NULL;
|
||||
}
|
||||
|
||||
/* Now complete the transaction by attaching the scriptSigs where necessary */
|
||||
for (size_t i=0; i<tal_count(inputs); i++)
|
||||
tx->input[i].script = scriptSigs[i];
|
||||
|
||||
daemon_conn_send(master,
|
||||
take(towire_hsm_sign_funding_reply(tmpctx, sig)));
|
||||
take(towire_hsm_sign_funding_reply(tmpctx, tx)));
|
||||
tal_free(tmpctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,8 +35,7 @@ hsm_sign_funding,,num_inputs,u16
|
||||
hsm_sign_funding,,inputs,num_inputs*struct utxo
|
||||
|
||||
hsm_sign_funding_reply,104
|
||||
hsm_sign_funding_reply,,num_sigs,u16
|
||||
hsm_sign_funding_reply,,sig,num_sigs*secp256k1_ecdsa_signature
|
||||
hsm_sign_funding_reply,,tx,struct bitcoin_tx
|
||||
|
||||
# Master asks the HSM to sign a node_announcement
|
||||
hsm_node_announcement_sig_req,6
|
||||
|
||||
@@ -1005,9 +1005,6 @@ struct funding_channel {
|
||||
|
||||
/* Peer, once we have one. */
|
||||
struct peer *peer;
|
||||
|
||||
/* Funding tx once we're ready to sign and send. */
|
||||
struct bitcoin_tx *funding_tx;
|
||||
};
|
||||
|
||||
static void funding_broadcast_failed(struct peer *peer,
|
||||
@@ -1583,35 +1580,15 @@ static void opening_got_hsm_funding_sig(struct funding_channel *fc,
|
||||
const struct crypto_state *cs,
|
||||
u64 gossip_index)
|
||||
{
|
||||
secp256k1_ecdsa_signature *sigs;
|
||||
struct bitcoin_tx *tx = fc->funding_tx;
|
||||
struct bitcoin_tx *tx = tal(fc, struct bitcoin_tx);
|
||||
u8 *linear;
|
||||
u64 change_satoshi;
|
||||
struct json_result *response = new_json_result(fc->cmd);
|
||||
size_t i;
|
||||
|
||||
if (!fromwire_hsm_sign_funding_reply(fc, resp, NULL, &sigs))
|
||||
if (!fromwire_hsm_sign_funding_reply(resp, NULL, tx))
|
||||
fatal("HSM gave bad sign_funding_reply %s",
|
||||
tal_hex(fc, resp));
|
||||
|
||||
if (tal_count(sigs) != tal_count(tx->input))
|
||||
fatal("HSM gave %zu sigs, needed %zu",
|
||||
tal_count(sigs), tal_count(tx->input));
|
||||
|
||||
/* Create input parts from signatures. */
|
||||
for (i = 0; i < tal_count(tx->input); i++) {
|
||||
struct pubkey key;
|
||||
|
||||
if (!bip32_pubkey(fc->peer->ld->wallet->bip32_base,
|
||||
&key, fc->utxomap[i]->keyindex))
|
||||
fatal("Cannot generate BIP32 key for UTXO %u",
|
||||
fc->utxomap[i]->keyindex);
|
||||
|
||||
/* P2SH inputs have same witness. */
|
||||
tx->input[i].witness
|
||||
= bitcoin_witness_p2wpkh(tx, &sigs[i], &key);
|
||||
}
|
||||
|
||||
/* Send it out and watch for confirms. */
|
||||
broadcast_tx(fc->peer->ld->topology, fc->peer, tx, funding_broadcast_failed);
|
||||
watch_tx(fc->peer, fc->peer->ld->topology, fc->peer, tx,
|
||||
@@ -2175,9 +2152,11 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
|
||||
const int *fds,
|
||||
struct funding_channel *fc)
|
||||
{
|
||||
tal_t *tmpctx = tal_tmpctx(fc);
|
||||
u8 *msg;
|
||||
struct channel_info *channel_info;
|
||||
struct utxo *utxos;
|
||||
struct bitcoin_tx *fundingtx;
|
||||
struct bitcoin_txid funding_txid;
|
||||
struct pubkey changekey;
|
||||
struct pubkey local_fundingkey;
|
||||
@@ -2233,25 +2212,27 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
|
||||
|
||||
derive_basepoints(fc->peer->seed, &local_fundingkey, NULL, NULL, NULL);
|
||||
|
||||
fc->funding_tx = funding_tx(fc, &fc->peer->funding_outnum,
|
||||
fc->utxomap, fc->peer->funding_satoshi,
|
||||
&local_fundingkey,
|
||||
&channel_info->remote_fundingkey,
|
||||
fc->change, &changekey,
|
||||
fc->peer->ld->wallet->bip32_base);
|
||||
fundingtx = funding_tx(tmpctx, &fc->peer->funding_outnum,
|
||||
fc->utxomap, fc->peer->funding_satoshi,
|
||||
&local_fundingkey,
|
||||
&channel_info->remote_fundingkey,
|
||||
fc->change, &changekey,
|
||||
fc->peer->ld->wallet->bip32_base);
|
||||
|
||||
log_debug(fc->peer->log, "Funding tx has %zi inputs, %zu outputs:",
|
||||
tal_count(fc->funding_tx->input),
|
||||
tal_count(fc->funding_tx->output));
|
||||
for (size_t i = 0; i < tal_count(fc->funding_tx->input); i++) {
|
||||
tal_count(fundingtx->input),
|
||||
tal_count(fundingtx->output));
|
||||
|
||||
for (size_t i = 0; i < tal_count(fundingtx->input); i++) {
|
||||
log_debug(fc->peer->log, "%zi: %"PRIu64" satoshi (%s) %s\n",
|
||||
i, fc->utxomap[i]->amount,
|
||||
fc->utxomap[i]->is_p2sh ? "P2SH" : "SEGWIT",
|
||||
type_to_string(ltmp, struct bitcoin_txid,
|
||||
&fc->funding_tx->input[i].txid));
|
||||
&fundingtx->input[i].txid));
|
||||
}
|
||||
|
||||
fc->peer->funding_txid = tal(fc->peer, struct bitcoin_txid);
|
||||
bitcoin_txid(fc->funding_tx, fc->peer->funding_txid);
|
||||
bitcoin_txid(fundingtx, fc->peer->funding_txid);
|
||||
|
||||
if (!structeq(fc->peer->funding_txid, &funding_txid)) {
|
||||
peer_internal_error(fc->peer,
|
||||
@@ -2276,20 +2257,20 @@ static void opening_funder_finished(struct subd *opening, const u8 *resp,
|
||||
/* Get HSM to sign the funding tx. */
|
||||
log_debug(fc->peer->log, "Getting HSM to sign funding tx");
|
||||
|
||||
utxos = from_utxoptr_arr(fc, fc->utxomap);
|
||||
msg = towire_hsm_sign_funding(fc, fc->peer->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
&local_fundingkey,
|
||||
&channel_info->remote_fundingkey,
|
||||
utxos);
|
||||
tal_free(utxos);
|
||||
|
||||
utxos = from_utxoptr_arr(tmpctx, fc->utxomap);
|
||||
msg = towire_hsm_sign_funding(tmpctx, fc->peer->funding_satoshi,
|
||||
fc->change, fc->change_keyindex,
|
||||
&local_fundingkey,
|
||||
&channel_info->remote_fundingkey,
|
||||
utxos);
|
||||
/* Unowned (will free openingd). */
|
||||
peer_set_owner(fc->peer, NULL);
|
||||
|
||||
if (!wire_sync_write(fc->peer->ld->hsm_fd, take(msg)))
|
||||
fatal("Could not write to HSM: %s", strerror(errno));
|
||||
|
||||
tal_free(tmpctx);
|
||||
|
||||
msg = hsm_sync_read(fc, fc->peer->ld);
|
||||
opening_got_hsm_funding_sig(fc, fds[0], fds[1], msg, &cs, gossip_index);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user