Browse Source

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>
pr-2587
Christian Decker 6 years ago
committed by Rusty Russell
parent
commit
9fe481b967
  1. 11
      bitcoin/tx.c
  2. 6
      bitcoin/tx.h
  3. 4
      channeld/channeld.c
  4. 10
      common/permute_tx.c
  5. 13
      hsmd/hsmd.c
  6. 10
      onchaind/onchaind.c
  7. 4
      onchaind/test/run-grind_feerate.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].txid = *txid;
tx->input[i].index = outnum; tx->input[i].index = outnum;
tx->input[i].sequence_number = sequence; tx->input[i].sequence_number = sequence;
tx->input[i].amount = tal_dup(tx, struct amount_sat, amount);
tx->input[i].script = script; tx->input[i].script = script;
assert(tx->wtx != NULL); 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_add_input(tx->wtx, input);
wally_tx_input_free(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++; tx->used_inputs++;
return i; return i;
} }
@ -347,7 +350,7 @@ static void hash_for_segwit(struct sha256_ctx *ctx,
push_varint_blob(witness_script, push_sha, ctx); push_varint_blob(witness_script, push_sha, ctx);
/* 6. value of the output spent by this input (8-byte little end) */ /* 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) */ /* 7. nSequence of the input (4-byte little endian) */
push_le32(tx->input[input_num].sequence_number, push_sha, ctx); 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); &tx->wtx);
tal_add_destructor(tx, bitcoin_tx_destroy); 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->output = tal_arrz(tx, struct bitcoin_tx_output, output_count);
tx->input = tal_arrz(tx, struct bitcoin_tx_input, input_count); tx->input = tal_arrz(tx, struct bitcoin_tx_input, input_count);
for (i = 0; i < tal_count(tx->input); i++) { for (i = 0; i < tal_count(tx->input); i++) {
/* We assume NULL is a zero bitmap */ /* We assume NULL is a zero bitmap */
assert(tx->input[i].script == NULL); assert(tx->input[i].script == NULL);
tx->input[i].sequence_number = BITCOIN_TX_DEFAULT_SEQUENCE; tx->input[i].sequence_number = BITCOIN_TX_DEFAULT_SEQUENCE;
tx->input[i].amount = NULL;
tx->input[i].witness = NULL; tx->input[i].witness = NULL;
} }
tx->wtx->locktime = 0; 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); tal_add_destructor(tx, bitcoin_tx_destroy);
wally_tx_get_length(tx->wtx, WALLY_TX_FLAG_USE_WITNESS, &wsize); 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); assert(pull_le32(cursor, max) == tx->wtx->version);
count = pull_length(cursor, max, 32 + 4 + 4 + 1); count = pull_length(cursor, max, 32 + 4 + 4 + 1);

6
bitcoin/tx.h

@ -19,6 +19,9 @@ struct bitcoin_txid {
STRUCTEQ_DEF(bitcoin_txid, 0, shad.sha.u); STRUCTEQ_DEF(bitcoin_txid, 0, shad.sha.u);
struct bitcoin_tx { 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_input *input;
struct bitcoin_tx_output *output; struct bitcoin_tx_output *output;
struct wally_tx *wtx; struct wally_tx *wtx;
@ -39,9 +42,6 @@ struct bitcoin_tx_input {
u8 *script; u8 *script;
u32 sequence_number; u32 sequence_number;
/* Value of the output we're spending (NULL if unknown). */
struct amount_sat *amount;
/* Only if BIP141 used. */ /* Only if BIP141 used. */
u8 **witness; u8 **witness;
}; };

4
channeld/channeld.c

@ -952,7 +952,7 @@ 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[0].amount); *txs[0]->input_amounts[0]);
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))
@ -989,7 +989,7 @@ static secp256k1_ecdsa_signature *calc_commitsigs(const tal_t *ctx,
struct bitcoin_signature sig; struct bitcoin_signature sig;
msg = towire_hsm_sign_remote_htlc_tx(NULL, txs[i + 1], msg = towire_hsm_sign_remote_htlc_tx(NULL, txs[i + 1],
wscripts[i + 1], wscripts[i + 1],
*txs[i+1]->input[0].amount, *txs[i+1]->input_amounts[0],
&peer->remote_per_commit); &peer->remote_per_commit);
msg = hsm_req(tmpctx, take(msg)); msg = hsm_req(tmpctx, take(msg));

10
common/permute_tx.c

@ -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) void permute_inputs(struct bitcoin_tx *tx, const void **map)
{ {
size_t i, best_pos; 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) if (tx->wtx->num_inputs == num_inputs)
/* TODO(cdecker) Set `map` once the old style is removed */ /* TODO(cdecker) Set `map` once the old style is removed */
swap_wally_inputs(tx->wtx->inputs, NULL, i, best_pos); swap_wally_inputs(tx->wtx->inputs, NULL, i, best_pos);
swap_input_amounts(tx->input_amounts, i, best_pos);
} }
} }

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 * 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 * 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. */ * 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, sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey, &secrets.funding_privkey,
&local_funding_pubkey, &local_funding_pubkey,
@ -818,7 +819,7 @@ static struct io_plan *handle_sign_remote_commitment_tx(struct io_conn *conn,
&local_funding_pubkey, &local_funding_pubkey,
&remote_funding_pubkey); &remote_funding_pubkey);
/* Need input amount for signing */ /* 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, sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey, &secrets.funding_privkey,
&local_funding_pubkey, &local_funding_pubkey,
@ -867,7 +868,7 @@ static struct io_plan *handle_sign_remote_htlc_tx(struct io_conn *conn,
"Failed deriving htlc pubkey"); "Failed deriving htlc pubkey");
/* Need input amount for signing */ /* 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, sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey,
SIGHASH_ALL, &sig); 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) if (tal_count(tx->input) != 1)
return bad_req_fmt(conn, c, msg_in, "bad txinput count"); 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); 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))); 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"); return bad_req_fmt(conn, c, msg_in, "bad txinput count");
/* FIXME: Check that output script is correct! */ /* 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, sign_tx_input(tx, 0, NULL, wscript, &htlc_privkey, &htlc_pubkey,
SIGHASH_ALL, &sig); SIGHASH_ALL, &sig);
@ -1208,7 +1209,7 @@ static struct io_plan *handle_sign_mutual_close_tx(struct io_conn *conn,
&local_funding_pubkey, &local_funding_pubkey,
&remote_funding_pubkey); &remote_funding_pubkey);
/* Need input amount for signing */ /* 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, sign_tx_input(tx, 0, NULL, funding_wscript,
&secrets.funding_privkey, &secrets.funding_privkey,
&local_funding_pubkey, &local_funding_pubkey,

10
onchaind/onchaind.c

@ -137,7 +137,7 @@ static bool grind_htlc_tx_fee(struct amount_sat *fee,
continue; continue;
prev_fee = *fee; prev_fee = *fee;
if (!amount_sat_sub(&out, *tx->input[0].amount, *fee)) if (!amount_sat_sub(&out, *tx->input_amounts[0], *fee))
break; break;
bitcoin_tx_output_set_amount(tx, 0, &out); 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, return towire_hsm_sign_delayed_payment_to_us(ctx, commit_num,
tx, wscript, tx, wscript,
*tx->input[0].amount); *tx->input_amounts[0]);
} }
static u8 *remote_htlc_to_us(const tal_t *ctx, 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, return towire_hsm_sign_remote_htlc_to_us(ctx,
remote_per_commitment_point, remote_per_commitment_point,
tx, wscript, tx, wscript,
*tx->input[0].amount); *tx->input_amounts[0]);
} }
static u8 *penalty_to_us(const tal_t *ctx, 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) const u8 *wscript)
{ {
return towire_hsm_sign_penalty_to_us(ctx, remote_per_commitment_secret, 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, u8 *msg = towire_hsm_sign_local_htlc_tx(NULL, commit_num,
tx, wscript, tx, wscript,
*tx->input[0].amount); *tx->input_amounts[0]);
if (!wire_sync_write(HSM_FD, take(msg))) if (!wire_sync_write(HSM_FD, take(msg)))
status_failed(STATUS_FAIL_HSM_IO, status_failed(STATUS_FAIL_HSM_IO,

4
onchaind/test/run-grind_feerate.c

@ -197,8 +197,8 @@ int main(int argc, char *argv[])
setup_tmpctx(); setup_tmpctx();
tx = bitcoin_tx_from_hex(tmpctx, "0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000", tx = bitcoin_tx_from_hex(tmpctx, "0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000",
strlen("0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000")); strlen("0200000001e1ebca08cf1c301ac563580a1126d5c8fcb0e5e2043230b852c726553caf1e1d0000000000000000000160ae0a000000000022002082e03c5a9cb79c82cd5a0572dc175290bc044609aabe9cc852d61927436041796d000000"));
tx->input[0].amount = tal(tx, struct amount_sat); tx->input_amounts[0] = tal(tx, struct amount_sat);
*tx->input[0].amount = AMOUNT_SAT(700000); *tx->input_amounts[0] = AMOUNT_SAT(700000);
der = tal_hexdata(tmpctx, "30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01", der = tal_hexdata(tmpctx, "30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01",
strlen("30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01")); strlen("30450221009b2e0eef267b94c3899fb0dc7375012e2cee4c10348a068fe78d1b82b4b14036022077c3fad3adac2ddf33f415e45f0daf6658b7a0b09647de4443938ae2dbafe2b9" "01"));
if (!signature_from_der(der, tal_count(der), &sig)) if (!signature_from_der(der, tal_count(der), &sig))

Loading…
Cancel
Save