From 0fe53cc8e7d2d731111edf85c1d28de73ab75920 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 7 Feb 2017 12:14:22 +1030 Subject: [PATCH] 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 --- close_tx.c | 2 +- daemon/commit_tx.c | 2 +- lightningd/commit_tx.c | 11 ++++++++++- lightningd/commit_tx.h | 1 + permute_tx.c | 19 +++++++++++++++---- permute_tx.h | 10 +++++++++- 6 files changed, 37 insertions(+), 8 deletions(-) diff --git a/close_tx.c b/close_tx.c index 44f4fc7fd..1f43d43e5 100644 --- a/close_tx.c +++ b/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); - permute_outputs(tx->output, 2); + permute_outputs(tx->output, 2, NULL); return tx; } diff --git a/daemon/commit_tx.c b/daemon/commit_tx.c index 200fe3096..8231bbc5c 100644 --- a/daemon/commit_tx.c +++ b/daemon/commit_tx.c @@ -218,7 +218,7 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx, assert(total <= peer->anchor.satoshis); 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); return tx; } diff --git a/lightningd/commit_tx.c b/lightningd/commit_tx.c index 30d578b6d..0a697c8c5 100644 --- a/lightningd/commit_tx.c +++ b/lightningd/commit_tx.c @@ -154,6 +154,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, u64 local_pay_msat, u64 remote_pay_msat, const struct htlc **htlcs, + const struct htlc ***htlcmap, u64 obscured_commitment_number) { 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. */ 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: * * 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); tx->output[n].amount = offered[i]->msatoshi / 1000; tx->output[n].script = scriptpubkey_p2wsh(tx, wscript); + (*htlcmap)[n] = offered[i]; SUPERVERBOSE("# HTLC offered amount %"PRIu64" wscript %s\n", tx->output[n].amount, tal_hex(tmpctx, wscript)); @@ -228,6 +233,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, &received[i]->rhash); tx->output[n].amount = received[i]->msatoshi / 1000; tx->output[n].script = scriptpubkey_p2wsh(tx, wscript); + (*htlcmap)[n] = received[i]; SUPERVERBOSE("# HTLC received amount %"PRIu64" wscript %s\n", tx->output[n].amount, tal_hex(tmpctx, wscript)); @@ -246,6 +252,7 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, local_delayedkey); tx->output[n].amount = local_pay_msat / 1000; tx->output[n].script = scriptpubkey_p2wsh(tx, wscript); + (*htlcmap)[n] = NULL; SUPERVERBOSE("# to-local amount %"PRIu64" wscript %s\n", tx->output[n].amount, 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].script = scriptpubkey_p2wpkh(tx, remotekey); + (*htlcmap)[n] = NULL; SUPERVERBOSE("# to-remote amount %"PRIu64" P2WPKH(%s)\n", tx->output[n].amount, 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)); tal_resize(&tx->output, n); + tal_resize(htlcmap, n); /* BOLT #3: * * 7. Sort the outputs into [BIP 69 * 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: * diff --git a/lightningd/commit_tx.h b/lightningd/commit_tx.h index 3bbbbe4e6..9d37ae28e 100644 --- a/lightningd/commit_tx.h +++ b/lightningd/commit_tx.h @@ -37,5 +37,6 @@ struct bitcoin_tx *commit_tx(const tal_t *ctx, u64 local_pay_msat, u64 remote_pay_msat, const struct htlc **htlcs, + const struct htlc ***htlcmap, u64 commit_number_obscurer); #endif /* LIGHTNING_LIGHTNINGD_COMMIT_TX_H */ diff --git a/permute_tx.c b/permute_tx.c index c1e5283ba..5c06c2274 100644 --- a/permute_tx.c +++ b/permute_tx.c @@ -33,7 +33,8 @@ static size_t find_best_in(struct bitcoin_tx_input *inputs, size_t num) 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; @@ -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, - size_t i1, size_t i2) + const struct htlc **htlcmap, + size_t i1, size_t i2) { struct bitcoin_tx_output tmpoutput; + const struct htlc *tmphtlc; tmpoutput = outputs[i1]; outputs[i1] = outputs[i2]; 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, @@ -97,14 +106,16 @@ static size_t find_best_out(struct bitcoin_tx_output *outputs, size_t num) 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; /* Now do a dumb sort (num_outputs is small). */ for (i = 0; i < num_outputs; i++) { /* Swap best into first place. */ - swap_outputs(outputs, + swap_outputs(outputs, htlcmap, i, i + find_best_out(outputs + i, num_outputs - i)); } } diff --git a/permute_tx.h b/permute_tx.h index a3c5c63d8..30416d5f2 100644 --- a/permute_tx.h +++ b/permute_tx.h @@ -3,8 +3,16 @@ #include "config.h" #include "bitcoin/tx.h" +struct htlc; + /* Permute the transaction into BIP69 order. */ 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 */