mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-26 20:30:59 +01:00
wally: Move input amounts into a separate array
The `wally_tx_input`s do not keep track of their input value, which means we need to track them ourselves if we try to sign these transactions at a later point in time. Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
parent
48006cb674
commit
9fe481b967
7 changed files with 37 additions and 21 deletions
11
bitcoin/tx.c
11
bitcoin/tx.c
|
@ -48,7 +48,6 @@ int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid,
|
|||
tx->input[i].txid = *txid;
|
||||
tx->input[i].index = outnum;
|
||||
tx->input[i].sequence_number = sequence;
|
||||
tx->input[i].amount = tal_dup(tx, struct amount_sat, amount);
|
||||
tx->input[i].script = script;
|
||||
|
||||
assert(tx->wtx != NULL);
|
||||
|
@ -59,6 +58,10 @@ int bitcoin_tx_add_input(struct bitcoin_tx *tx, const struct bitcoin_txid *txid,
|
|||
wally_tx_add_input(tx->wtx, input);
|
||||
wally_tx_input_free(input);
|
||||
|
||||
/* Now store the input amount if we know it, so we can sign later */
|
||||
tx->input_amounts[i] = tal_free(tx->input_amounts[i]);
|
||||
tx->input_amounts[i] = tal_dup(tx, struct amount_sat, amount);
|
||||
|
||||
tx->used_inputs++;
|
||||
return i;
|
||||
}
|
||||
|
@ -347,7 +350,7 @@ static void hash_for_segwit(struct sha256_ctx *ctx,
|
|||
push_varint_blob(witness_script, push_sha, ctx);
|
||||
|
||||
/* 6. value of the output spent by this input (8-byte little end) */
|
||||
push_amount_sat(*tx->input[input_num].amount, push_sha, ctx);
|
||||
push_amount_sat(*tx->input_amounts[input_num], push_sha, ctx);
|
||||
|
||||
/* 7. nSequence of the input (4-byte little endian) */
|
||||
push_le32(tx->input[input_num].sequence_number, push_sha, ctx);
|
||||
|
@ -450,13 +453,13 @@ struct bitcoin_tx *bitcoin_tx(const tal_t *ctx, varint_t input_count,
|
|||
&tx->wtx);
|
||||
tal_add_destructor(tx, bitcoin_tx_destroy);
|
||||
|
||||
tx->input_amounts = tal_arrz(tx, struct amount_sat*, input_count);
|
||||
tx->output = tal_arrz(tx, struct bitcoin_tx_output, output_count);
|
||||
tx->input = tal_arrz(tx, struct bitcoin_tx_input, input_count);
|
||||
for (i = 0; i < tal_count(tx->input); i++) {
|
||||
/* We assume NULL is a zero bitmap */
|
||||
assert(tx->input[i].script == NULL);
|
||||
tx->input[i].sequence_number = BITCOIN_TX_DEFAULT_SEQUENCE;
|
||||
tx->input[i].amount = NULL;
|
||||
tx->input[i].witness = NULL;
|
||||
}
|
||||
tx->wtx->locktime = 0;
|
||||
|
@ -565,6 +568,8 @@ struct bitcoin_tx *pull_bitcoin_tx(const tal_t *ctx, const u8 **cursor,
|
|||
}
|
||||
tal_add_destructor(tx, bitcoin_tx_destroy);
|
||||
wally_tx_get_length(tx->wtx, WALLY_TX_FLAG_USE_WITNESS, &wsize);
|
||||
tx->input_amounts =
|
||||
tal_arrz(tx, struct amount_sat *, tx->wtx->inputs_allocation_len);
|
||||
|
||||
assert(pull_le32(cursor, max) == tx->wtx->version);
|
||||
count = pull_length(cursor, max, 32 + 4 + 4 + 1);
|
||||
|
|
|
@ -19,6 +19,9 @@ struct bitcoin_txid {
|
|||
STRUCTEQ_DEF(bitcoin_txid, 0, shad.sha.u);
|
||||
|
||||
struct bitcoin_tx {
|
||||
/* Keep track of input amounts, this is needed for signatures (NULL if
|
||||
* unknown) */
|
||||
struct amount_sat **input_amounts;
|
||||
struct bitcoin_tx_input *input;
|
||||
struct bitcoin_tx_output *output;
|
||||
struct wally_tx *wtx;
|
||||
|
@ -39,9 +42,6 @@ struct bitcoin_tx_input {
|
|||
u8 *script;
|
||||
u32 sequence_number;
|
||||
|
||||
/* Value of the output we're spending (NULL if unknown). */
|
||||
struct amount_sat *amount;
|
||||
|
||||
/* Only if BIP141 used. */
|
||||
u8 **witness;
|
||||
};
|
||||
|
|
|
@ -952,7 +952,7 @@ 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[0].amount);
|
||||
*txs[0]->input_amounts[0]);
|
||||
|
||||
msg = hsm_req(tmpctx, take(msg));
|
||||
if (!fromwire_hsm_sign_tx_reply(msg, commit_sig))
|
||||
|
@ -989,7 +989,7 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx,
|
|||
struct bitcoin_signature sig;
|
||||
msg = towire_hsm_sign_remote_htlc_tx(NULL, txs[i + 1],
|
||||
wscripts[i + 1],
|
||||
*txs[i+1]->input[0].amount,
|
||||
*txs[i+1]->input_amounts[0],
|
||||
&peer->remote_per_commit);
|
||||
|
||||
msg = hsm_req(tmpctx, take(msg));
|
||||
|
|
|
@ -75,6 +75,14 @@ static void swap_wally_inputs(struct wally_tx_input *inputs,
|
|||
}
|
||||
}
|
||||
|
||||
static void swap_input_amounts(struct amount_sat **amounts, size_t i1,
|
||||
size_t i2)
|
||||
{
|
||||
struct amount_sat *tmp = amounts[i1];
|
||||
amounts[i1] = amounts[i2];
|
||||
amounts[i2] = tmp;
|
||||
}
|
||||
|
||||
void permute_inputs(struct bitcoin_tx *tx, const void **map)
|
||||
{
|
||||
size_t i, best_pos;
|
||||
|
@ -95,6 +103,8 @@ void permute_inputs(struct bitcoin_tx *tx, const void **map)
|
|||
if (tx->wtx->num_inputs == num_inputs)
|
||||
/* TODO(cdecker) Set `map` once the old style is removed */
|
||||
swap_wally_inputs(tx->wtx->inputs, NULL, i, best_pos);
|
||||
|
||||
swap_input_amounts(tx->input_amounts, i, best_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
13
hsmd/hsmd.c
13
hsmd/hsmd.c
|
@ -773,7 +773,8 @@ static struct io_plan *handle_sign_commitment_tx(struct io_conn *conn,
|
|||
* pointer, as we don't always know it (and zero is a valid amount, so
|
||||
* NULL is better to mean 'unknown' and has the nice property that
|
||||
* you'll crash if you assume it's there and you're wrong. */
|
||||
tx->input[0].amount = tal_dup(tx->input, struct amount_sat, &funding);
|
||||
tx->input_amounts[0] = tal_dup(tx->input, struct amount_sat, &funding);
|
||||
tx->input_amounts[0] = tx->input_amounts[0];
|
||||
sign_tx_input(tx, 0, NULL, funding_wscript,
|
||||
&secrets.funding_privkey,
|
||||
&local_funding_pubkey,
|
||||
|
@ -818,7 +819,7 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
|
|||
&local_funding_pubkey,
|
||||
&remote_funding_pubkey);
|
||||
/* Need input amount for signing */
|
||||
tx->input[0].amount = tal_dup(tx->input, struct amount_sat, &funding);
|
||||
tx->input_amounts[0] = tal_dup(tx->input, struct amount_sat, &funding);
|
||||
sign_tx_input(tx, 0, NULL, funding_wscript,
|
||||
&secrets.funding_privkey,
|
||||
&local_funding_pubkey,
|
||||
|
@ -867,7 +868,7 @@ static struct io_plan *handle_sign_remote_htlc_tx(struct io_conn *conn,
|
|||
"Failed deriving htlc pubkey");
|
||||
|
||||
/* Need input amount for signing */
|
||||
tx->input[0].amount = tal_dup(tx->input, struct amount_sat, &amount);
|
||||
tx->input_amounts[0] = tal_dup(tx->input, struct amount_sat, &amount);
|
||||
sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey,
|
||||
SIGHASH_ALL, &sig);
|
||||
|
||||
|
@ -894,7 +895,7 @@ static struct io_plan *handle_sign_to_us_tx(struct io_conn *conn,
|
|||
if (tal_count(tx->input) != 1)
|
||||
return bad_req_fmt(conn, c, msg_in, "bad txinput count");
|
||||
|
||||
tx->input[0].amount = tal_dup(tx->input, struct amount_sat, &input_sat);
|
||||
tx->input_amounts[0] = tal_dup(tx->input, struct amount_sat, &input_sat);
|
||||
sign_tx_input(tx, 0, NULL, wscript, privkey, &pubkey, SIGHASH_ALL, &sig);
|
||||
|
||||
return req_reply(conn, c, take(towire_hsm_sign_tx_reply(NULL, &sig)));
|
||||
|
@ -1093,7 +1094,7 @@ static struct io_plan *handle_sign_local_htlc_tx(struct io_conn *conn,
|
|||
return bad_req_fmt(conn, c, msg_in, "bad txinput count");
|
||||
|
||||
/* FIXME: Check that output script is correct! */
|
||||
tx->input[0].amount = tal_dup(tx->input, struct amount_sat, &input_sat);
|
||||
tx->input_amounts[0] = tal_dup(tx->input, struct amount_sat, &input_sat);
|
||||
sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey,
|
||||
SIGHASH_ALL, &sig);
|
||||
|
||||
|
@ -1208,7 +1209,7 @@ static struct io_plan *handle_sign_mutual_close_tx(struct io_conn *conn,
|
|||
&local_funding_pubkey,
|
||||
&remote_funding_pubkey);
|
||||
/* Need input amount for signing */
|
||||
tx->input[0].amount = tal_dup(tx->input, struct amount_sat, &funding);
|
||||
tx->input_amounts[0] = tal_dup(tx->input, struct amount_sat, &funding);
|
||||
sign_tx_input(tx, 0, NULL, funding_wscript,
|
||||
&secrets.funding_privkey,
|
||||
&local_funding_pubkey,
|
||||
|
|
|
@ -137,7 +137,7 @@ static bool grind_htlc_tx_fee(struct amount_sat *fee,
|
|||
continue;
|
||||
|
||||
prev_fee = *fee;
|
||||
if (!amount_sat_sub(&out, *tx->input[0].amount, *fee))
|
||||
if (!amount_sat_sub(&out, *tx->input_amounts[0], *fee))
|
||||
break;
|
||||
|
||||
bitcoin_tx_output_set_amount(tx, 0, &out);
|
||||
|
@ -252,7 +252,7 @@ static u8 *delayed_payment_to_us(const tal_t *ctx,
|
|||
{
|
||||
return towire_hsm_sign_delayed_payment_to_us(ctx, commit_num,
|
||||
tx, wscript,
|
||||
*tx->input[0].amount);
|
||||
*tx->input_amounts[0]);
|
||||
}
|
||||
|
||||
static u8 *remote_htlc_to_us(const tal_t *ctx,
|
||||
|
@ -262,7 +262,7 @@ static u8 *remote_htlc_to_us(const tal_t *ctx,
|
|||
return towire_hsm_sign_remote_htlc_to_us(ctx,
|
||||
remote_per_commitment_point,
|
||||
tx, wscript,
|
||||
*tx->input[0].amount);
|
||||
*tx->input_amounts[0]);
|
||||
}
|
||||
|
||||
static u8 *penalty_to_us(const tal_t *ctx,
|
||||
|
@ -270,7 +270,7 @@ static u8 *penalty_to_us(const tal_t *ctx,
|
|||
const u8 *wscript)
|
||||
{
|
||||
return towire_hsm_sign_penalty_to_us(ctx, remote_per_commitment_secret,
|
||||
tx, wscript, *tx->input[0].amount);
|
||||
tx, wscript, *tx->input_amounts[0]);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -365,7 +365,7 @@ static void hsm_sign_local_htlc_tx(struct bitcoin_tx *tx,
|
|||
{
|
||||
u8 *msg = towire_hsm_sign_local_htlc_tx(NULL, commit_num,
|
||||
tx, wscript,
|
||||
*tx->input[0].amount);
|
||||
*tx->input_amounts[0]);
|
||||
|
||||
if (!wire_sync_write(HSM_FD, take(msg)))
|
||||
status_failed(STATUS_FAIL_HSM_IO,
|
||||
|
|
|
@ -197,8 +197,8 @@ int main(int argc, char *argv[])
|
|||
setup_tmpctx();
|
||||
tx = bitcoin_tx_from_hex(tmpctx, "0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000",
|
||||
strlen("0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000"));
|
||||
tx->input[0].amount = tal(tx, struct amount_sat);
|
||||
*tx->input[0].amount = AMOUNT_SAT(700000);
|
||||
tx->input_amounts[0] = tal(tx, struct amount_sat);
|
||||
*tx->input_amounts[0] = AMOUNT_SAT(700000);
|
||||
der = tal_hexdata(tmpctx, "30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01",
|
||||
strlen("30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01"));
|
||||
if (!signature_from_der(der, tal_count(der), &sig))
|
||||
|
|
Loading…
Add table
Reference in a new issue