mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
hsm: Generate fully signed transactions and return them to caller
So far we have been generating the tx both in the HSM and in the caller, and had to rely on them generating exactly the same transaction. This makes it a lot simpler by fully signing and serializing the TX on the HSM side and the caller just needs to unpack and broadcast it. Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
248879e203
commit
ce845853b0
23
hsmd/hsm.c
23
hsmd/hsm.c
@ -601,8 +601,8 @@ static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg)
|
|||||||
u32 change_keyindex;
|
u32 change_keyindex;
|
||||||
struct utxo *inutxos;
|
struct utxo *inutxos;
|
||||||
const struct utxo **utxos;
|
const struct utxo **utxos;
|
||||||
secp256k1_ecdsa_signature *sigs;
|
|
||||||
u8 *wscript;
|
u8 *wscript;
|
||||||
|
u8 **scriptSigs;
|
||||||
struct bitcoin_tx *tx;
|
struct bitcoin_tx *tx;
|
||||||
struct ext_key ext;
|
struct ext_key ext;
|
||||||
struct pubkey changekey;
|
struct pubkey changekey;
|
||||||
@ -630,13 +630,13 @@ static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg)
|
|||||||
tmpctx, utxos, scriptpubkey, satoshi_out,
|
tmpctx, utxos, scriptpubkey, satoshi_out,
|
||||||
&changekey, change_out, NULL);
|
&changekey, change_out, NULL);
|
||||||
|
|
||||||
/* Now generate signatures. */
|
scriptSigs = tal_arr(tmpctx, u8*, tal_count(utxos));
|
||||||
sigs = tal_arr(tmpctx, secp256k1_ecdsa_signature, tal_count(utxos));
|
|
||||||
for (size_t i = 0; i < tal_count(utxos); i++) {
|
for (size_t i = 0; i < tal_count(utxos); i++) {
|
||||||
struct pubkey inkey;
|
struct pubkey inkey;
|
||||||
struct privkey inprivkey;
|
struct privkey inprivkey;
|
||||||
const struct utxo *in = utxos[i];
|
const struct utxo *in = utxos[i];
|
||||||
u8 *subscript;
|
u8 *subscript;
|
||||||
|
secp256k1_ecdsa_signature sig;
|
||||||
|
|
||||||
bitcoin_keypair(&inprivkey, &inkey, in->keyindex);
|
bitcoin_keypair(&inprivkey, &inkey, in->keyindex);
|
||||||
if (utxos[i]->is_p2sh)
|
if (utxos[i]->is_p2sh)
|
||||||
@ -645,12 +645,23 @@ static void sign_withdrawal_tx(struct daemon_conn *master, const u8 *msg)
|
|||||||
subscript = NULL;
|
subscript = NULL;
|
||||||
wscript = p2wpkh_scriptcode(tmpctx, &inkey);
|
wscript = p2wpkh_scriptcode(tmpctx, &inkey);
|
||||||
|
|
||||||
sign_tx_input(tx, i, subscript, wscript,
|
sign_tx_input(tx, i, subscript, wscript, &inprivkey, &inkey,
|
||||||
&inprivkey, &inkey, &sigs[i]);
|
&sig);
|
||||||
|
|
||||||
|
tx->input[i].witness = bitcoin_witness_p2wpkh(tx, &sig, &inkey);
|
||||||
|
|
||||||
|
if (utxos[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(utxos); i++)
|
||||||
|
tx->input[i].script = scriptSigs[i];
|
||||||
|
|
||||||
daemon_conn_send(master,
|
daemon_conn_send(master,
|
||||||
take(towire_hsm_sign_withdrawal_reply(tmpctx, sigs)));
|
take(towire_hsm_sign_withdrawal_reply(tmpctx, tx)));
|
||||||
tal_free(tmpctx);
|
tal_free(tmpctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,8 +57,7 @@ hsm_sign_withdrawal,,num_inputs,u16
|
|||||||
hsm_sign_withdrawal,,inputs,num_inputs*struct utxo
|
hsm_sign_withdrawal,,inputs,num_inputs*struct utxo
|
||||||
|
|
||||||
hsm_sign_withdrawal_reply,107
|
hsm_sign_withdrawal_reply,107
|
||||||
hsm_sign_withdrawal_reply,,num_sigs,u16
|
hsm_sign_withdrawal_reply,,tx,struct bitcoin_tx
|
||||||
hsm_sign_withdrawal_reply,,sig,num_sigs*secp256k1_ecdsa_signature
|
|
||||||
|
|
||||||
# Sign an invoice
|
# Sign an invoice
|
||||||
hsm_sign_invoice,8
|
hsm_sign_invoice,8
|
||||||
|
@ -194,9 +194,6 @@ static void json_withdraw(struct command *cmd,
|
|||||||
u32 feerate_per_kw = get_feerate(cmd->ld->topology, FEERATE_NORMAL);
|
u32 feerate_per_kw = get_feerate(cmd->ld->topology, FEERATE_NORMAL);
|
||||||
u64 fee_estimate;
|
u64 fee_estimate;
|
||||||
struct utxo *utxos;
|
struct utxo *utxos;
|
||||||
struct ext_key ext;
|
|
||||||
struct pubkey changekey;
|
|
||||||
secp256k1_ecdsa_signature *sigs;
|
|
||||||
struct bitcoin_tx *tx;
|
struct bitcoin_tx *tx;
|
||||||
bool withdraw_all = false;
|
bool withdraw_all = false;
|
||||||
|
|
||||||
@ -293,43 +290,12 @@ static void json_withdraw(struct command *cmd,
|
|||||||
|
|
||||||
msg = hsm_sync_read(cmd, cmd->ld);
|
msg = hsm_sync_read(cmd, cmd->ld);
|
||||||
|
|
||||||
if (!fromwire_hsm_sign_withdrawal_reply(withdraw, msg, NULL, &sigs))
|
tx = tal(withdraw, struct bitcoin_tx);
|
||||||
|
|
||||||
|
if (!fromwire_hsm_sign_withdrawal_reply(msg, NULL, tx))
|
||||||
fatal("HSM gave bad sign_withdrawal_reply %s",
|
fatal("HSM gave bad sign_withdrawal_reply %s",
|
||||||
tal_hex(withdraw, msg));
|
tal_hex(withdraw, msg));
|
||||||
|
|
||||||
if (withdraw->changesatoshi) {
|
|
||||||
if (bip32_key_from_parent(cmd->ld->wallet->bip32_base,
|
|
||||||
withdraw->change_key_index,
|
|
||||||
BIP32_FLAG_KEY_PUBLIC, &ext)
|
|
||||||
!= WALLY_OK) {
|
|
||||||
command_fail(cmd, "Changekey generation failure");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
pubkey_from_der(ext.pub_key, sizeof(ext.pub_key), &changekey);
|
|
||||||
}
|
|
||||||
tx = withdraw_tx(withdraw, withdraw->utxos, withdraw->destination,
|
|
||||||
withdraw->amount, &changekey, withdraw->changesatoshi,
|
|
||||||
cmd->ld->wallet->bip32_base);
|
|
||||||
|
|
||||||
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 (size_t i = 0; i < tal_count(tx->input); i++) {
|
|
||||||
struct pubkey key;
|
|
||||||
|
|
||||||
if (!bip32_pubkey(cmd->ld->wallet->bip32_base,
|
|
||||||
&key, withdraw->utxos[i]->keyindex))
|
|
||||||
fatal("Cannot generate BIP32 key for UTXO %u",
|
|
||||||
withdraw->utxos[i]->keyindex);
|
|
||||||
|
|
||||||
/* P2SH inputs have same witness. */
|
|
||||||
tx->input[i].witness
|
|
||||||
= bitcoin_witness_p2wpkh(tx, &sigs[i], &key);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now broadcast the transaction */
|
/* Now broadcast the transaction */
|
||||||
withdraw->hextx = tal_hex(withdraw, linearize_tx(cmd, tx));
|
withdraw->hextx = tal_hex(withdraw, linearize_tx(cmd, tx));
|
||||||
bitcoind_sendrawtx(cmd->ld->topology->bitcoind, withdraw->hextx,
|
bitcoind_sendrawtx(cmd->ld->topology->bitcoind, withdraw->hextx,
|
||||||
|
Loading…
Reference in New Issue
Block a user