mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 23:24:27 +01:00
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>
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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:
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
17
permute_tx.c
17
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,
|
||||||
|
const struct htlc **htlcmap,
|
||||||
size_t i1, size_t i2)
|
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
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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user