Browse Source

permute_tx: reintroduce permute map.

We used to have a permutation map; this reintroduces a variant which
uses the htlc pointers directly.

We need this because we have to send the htlc-tx signatures in output
order as part of the protocol: without two-stage HTLCs we only needed
to wire them up in the unilateral spend case so we simply brute-forced
the ordering.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
0fe53cc8e7
  1. 2
      close_tx.c
  2. 2
      daemon/commit_tx.c
  3. 11
      lightningd/commit_tx.c
  4. 1
      lightningd/commit_tx.h
  5. 19
      permute_tx.c
  6. 10
      permute_tx.h

2
close_tx.c

@ -35,6 +35,6 @@ struct bitcoin_tx *create_close_tx(const tal_t *ctx,
assert(tx->output[0].amount + tx->output[1].amount <= anchor_satoshis); assert(tx->output[0].amount + tx->output[1].amount <= anchor_satoshis);
permute_outputs(tx->output, 2); permute_outputs(tx->output, 2, NULL);
return tx; return tx;
} }

2
daemon/commit_tx.c

@ -218,7 +218,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
assert(total <= peer->anchor.satoshis); assert(total <= peer->anchor.satoshis);
tal_resize(&tx->output, output_count); tal_resize(&tx->output, output_count);
permute_outputs(tx->output, tal_count(tx->output)); permute_outputs(tx->output, tal_count(tx->output), NULL);
tal_free(tmpctx); tal_free(tmpctx);
return tx; return tx;
} }

11
lightningd/commit_tx.c

@ -154,6 +154,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
u64 local_pay_msat, u64 local_pay_msat,
u64 remote_pay_msat, u64 remote_pay_msat,
const struct htlc **htlcs, const struct htlc **htlcs,
const struct htlc ***htlcmap,
u64 obscured_commitment_number) u64 obscured_commitment_number)
{ {
const tal_t *tmpctx = tal_tmpctx(ctx); const tal_t *tmpctx = tal_tmpctx(ctx);
@ -199,6 +200,9 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
/* Worst-case sizing: both to-local and to-remote outputs. */ /* Worst-case sizing: both to-local and to-remote outputs. */
tx = bitcoin_tx(ctx, 1, tal_count(offered) + tal_count(received) + 2); tx = bitcoin_tx(ctx, 1, tal_count(offered) + tal_count(received) + 2);
/* We keep track of which outputs have which HTLCs */
*htlcmap = tal_arr(tx, const struct htlc *, tal_count(tx->output));
/* BOLT #3: /* BOLT #3:
* *
* 3. For every offered HTLC, if it is not trimmed, add an [offered * 3. For every offered HTLC, if it is not trimmed, add an [offered
@ -211,6 +215,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
&offered[i]->rhash); &offered[i]->rhash);
tx->output[n].amount = offered[i]->msatoshi / 1000; tx->output[n].amount = offered[i]->msatoshi / 1000;
tx->output[n].script = scriptpubkey_p2wsh(tx, wscript); tx->output[n].script = scriptpubkey_p2wsh(tx, wscript);
(*htlcmap)[n] = offered[i];
SUPERVERBOSE("# HTLC offered amount %"PRIu64" wscript %s\n", SUPERVERBOSE("# HTLC offered amount %"PRIu64" wscript %s\n",
tx->output[n].amount, tx->output[n].amount,
tal_hex(tmpctx, wscript)); tal_hex(tmpctx, wscript));
@ -228,6 +233,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
&received[i]->rhash); &received[i]->rhash);
tx->output[n].amount = received[i]->msatoshi / 1000; tx->output[n].amount = received[i]->msatoshi / 1000;
tx->output[n].script = scriptpubkey_p2wsh(tx, wscript); tx->output[n].script = scriptpubkey_p2wsh(tx, wscript);
(*htlcmap)[n] = received[i];
SUPERVERBOSE("# HTLC received amount %"PRIu64" wscript %s\n", SUPERVERBOSE("# HTLC received amount %"PRIu64" wscript %s\n",
tx->output[n].amount, tx->output[n].amount,
tal_hex(tmpctx, wscript)); tal_hex(tmpctx, wscript));
@ -246,6 +252,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
local_delayedkey); local_delayedkey);
tx->output[n].amount = local_pay_msat / 1000; tx->output[n].amount = local_pay_msat / 1000;
tx->output[n].script = scriptpubkey_p2wsh(tx, wscript); tx->output[n].script = scriptpubkey_p2wsh(tx, wscript);
(*htlcmap)[n] = NULL;
SUPERVERBOSE("# to-local amount %"PRIu64" wscript %s\n", SUPERVERBOSE("# to-local amount %"PRIu64" wscript %s\n",
tx->output[n].amount, tx->output[n].amount,
tal_hex(tmpctx, wscript)); tal_hex(tmpctx, wscript));
@ -268,6 +275,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
*/ */
tx->output[n].amount = remote_pay_msat / 1000; tx->output[n].amount = remote_pay_msat / 1000;
tx->output[n].script = scriptpubkey_p2wpkh(tx, remotekey); tx->output[n].script = scriptpubkey_p2wpkh(tx, remotekey);
(*htlcmap)[n] = NULL;
SUPERVERBOSE("# to-remote amount %"PRIu64" P2WPKH(%s)\n", SUPERVERBOSE("# to-remote amount %"PRIu64" P2WPKH(%s)\n",
tx->output[n].amount, tx->output[n].amount,
type_to_string(tmpctx, struct pubkey, remotekey)); type_to_string(tmpctx, struct pubkey, remotekey));
@ -276,13 +284,14 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
assert(n <= tal_count(tx->output)); assert(n <= tal_count(tx->output));
tal_resize(&tx->output, n); tal_resize(&tx->output, n);
tal_resize(htlcmap, n);
/* BOLT #3: /* BOLT #3:
* *
* 7. Sort the outputs into [BIP 69 * 7. Sort the outputs into [BIP 69
* order](#transaction-input-and-output-ordering) * order](#transaction-input-and-output-ordering)
*/ */
permute_outputs(tx->output, tal_count(tx->output)); permute_outputs(tx->output, tal_count(tx->output), *htlcmap);
/* BOLT #3: /* BOLT #3:
* *

1
lightningd/commit_tx.h

@ -37,5 +37,6 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx,
u64 local_pay_msat, u64 local_pay_msat,
u64 remote_pay_msat, u64 remote_pay_msat,
const struct htlc **htlcs, const struct htlc **htlcs,
const struct htlc ***htlcmap,
u64 commit_number_obscurer); u64 commit_number_obscurer);
#endif /* LIGHTNING_LIGHTNINGD_COMMIT_TX_H */ #endif /* LIGHTNING_LIGHTNINGD_COMMIT_TX_H */

19
permute_tx.c

@ -33,7 +33,8 @@ static size_t find_best_in(struct bitcoin_tx_input *inputs, size_t num)
return best; return best;
} }
static void swap_inputs(struct bitcoin_tx_input *inputs, size_t i1, size_t i2) static void swap_inputs(struct bitcoin_tx_input *inputs,
size_t i1, size_t i2)
{ {
struct bitcoin_tx_input tmpinput; struct bitcoin_tx_input tmpinput;
@ -55,13 +56,21 @@ void permute_inputs(struct bitcoin_tx_input *inputs, size_t num_inputs)
} }
static void swap_outputs(struct bitcoin_tx_output *outputs, static void swap_outputs(struct bitcoin_tx_output *outputs,
size_t i1, size_t i2) const struct htlc **htlcmap,
size_t i1, size_t i2)
{ {
struct bitcoin_tx_output tmpoutput; struct bitcoin_tx_output tmpoutput;
const struct htlc *tmphtlc;
tmpoutput = outputs[i1]; tmpoutput = outputs[i1];
outputs[i1] = outputs[i2]; outputs[i1] = outputs[i2];
outputs[i2] = tmpoutput; outputs[i2] = tmpoutput;
if (htlcmap) {
tmphtlc = htlcmap[i1];
htlcmap[i1] = htlcmap[i2];
htlcmap[i2] = tmphtlc;
}
} }
static bool output_better(const struct bitcoin_tx_output *a, static bool output_better(const struct bitcoin_tx_output *a,
@ -97,14 +106,16 @@ static size_t find_best_out(struct bitcoin_tx_output *outputs, size_t num)
return best; return best;
} }
void permute_outputs(struct bitcoin_tx_output *outputs, size_t num_outputs) void permute_outputs(struct bitcoin_tx_output *outputs,
size_t num_outputs,
const struct htlc **htlcmap)
{ {
size_t i; size_t i;
/* Now do a dumb sort (num_outputs is small). */ /* Now do a dumb sort (num_outputs is small). */
for (i = 0; i < num_outputs; i++) { for (i = 0; i < num_outputs; i++) {
/* Swap best into first place. */ /* Swap best into first place. */
swap_outputs(outputs, swap_outputs(outputs, htlcmap,
i, i + find_best_out(outputs + i, num_outputs - i)); i, i + find_best_out(outputs + i, num_outputs - i));
} }
} }

10
permute_tx.h

@ -3,8 +3,16 @@
#include "config.h" #include "config.h"
#include "bitcoin/tx.h" #include "bitcoin/tx.h"
struct htlc;
/* Permute the transaction into BIP69 order. */ /* Permute the transaction into BIP69 order. */
void permute_inputs(struct bitcoin_tx_input *inputs, size_t num_inputs); void permute_inputs(struct bitcoin_tx_input *inputs, size_t num_inputs);
void permute_outputs(struct bitcoin_tx_output *outputs, size_t num_outputs); /* If @htlcmap is non-NULL, it will be permuted the same as the outputs.
*
* So the caller initiates the htlcsmap with which htlcs are used, it
* can easily see which htlc (if any) is in output #0 with htlcmap[0].
*/
void permute_outputs(struct bitcoin_tx_output *outputs, size_t num_outputs,
const struct htlc **htlcmap);
#endif /* LIGHTNING_PERMUTE_TX_H */ #endif /* LIGHTNING_PERMUTE_TX_H */

Loading…
Cancel
Save