Browse Source

permute_tx: don't save permutation map.

We no longer need it anywhere.  This simplifies things to the point where
we might as well just not include dust outputs as we go, rather than
explicitly removing them, which gets rid of remove_dust.c as well.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
23f9c7c209
  1. 1
      Makefile
  2. 2
      close_tx.c
  3. 50
      daemon/commit_tx.c
  4. 3
      daemon/commit_tx.h
  5. 10
      daemon/peer.c
  6. 2
      daemon/peer.h
  7. 65
      permute_tx.c
  8. 12
      permute_tx.h
  9. 28
      remove_dust.c
  10. 4
      remove_dust.h

1
Makefile

@ -47,7 +47,6 @@ CORE_SRC := \
opt_bits.c \ opt_bits.c \
permute_tx.c \ permute_tx.c \
protobuf_convert.c \ protobuf_convert.c \
remove_dust.c \
utils.c \ utils.c \
version.c version.c
CORE_OBJS := $(CORE_SRC:.c=.o) CORE_OBJS := $(CORE_SRC:.c=.o)

2
close_tx.c

@ -38,6 +38,6 @@ struct bitcoin_tx *create_close_tx(secp256k1_context *secpctx,
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, NULL); permute_outputs(tx->output, 2);
return tx; return tx;
} }

50
daemon/commit_tx.c

@ -111,16 +111,27 @@ u8 *commit_output_to_them(const tal_t *ctx,
} }
} }
static void add_output(struct bitcoin_tx *tx, u8 *script, u64 amount,
u64 *total)
{
assert(tx->output_count < tal_count(tx->output));
if (is_dust(amount))
return;
tx->output[tx->output_count].script = script;
tx->output[tx->output_count].script_length = tal_count(script);
tx->output[tx->output_count].amount = amount;
tx->output_count++;
(*total) += amount;
}
struct bitcoin_tx *create_commit_tx(const tal_t *ctx, struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
struct peer *peer, struct peer *peer,
const struct sha256 *rhash, const struct sha256 *rhash,
const struct channel_state *cstate, const struct channel_state *cstate,
enum htlc_side side, enum htlc_side side)
int **map)
{ {
struct bitcoin_tx *tx; struct bitcoin_tx *tx;
size_t num; uint64_t total = 0;
uint64_t total;
struct htlc_map_iter it; struct htlc_map_iter it;
struct htlc *h; struct htlc *h;
int committed_flag = HTLC_FLAG(side,HTLC_F_COMMITTED); int committed_flag = HTLC_FLAG(side,HTLC_F_COMMITTED);
@ -133,38 +144,25 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
tx->input[0].index = peer->anchor.index; tx->input[0].index = peer->anchor.index;
tx->input[0].amount = tal_dup(tx->input, u64, &peer->anchor.satoshis); tx->input[0].amount = tal_dup(tx->input, u64, &peer->anchor.satoshis);
tx->output[0].script = commit_output_to_us(tx, peer, rhash, side, NULL); tx->output_count = 0;
tx->output[0].script_length = tal_count(tx->output[0].script); add_output(tx, commit_output_to_us(tx, peer, rhash, side, NULL),
tx->output[0].amount = cstate->side[OURS].pay_msat / 1000; cstate->side[OURS].pay_msat / 1000, &total);
add_output(tx, commit_output_to_them(tx, peer, rhash, side, NULL),
tx->output[1].script = commit_output_to_them(tx, peer, rhash, side,NULL); cstate->side[THEIRS].pay_msat / 1000, &total);
tx->output[1].script_length = tal_count(tx->output[1].script);
tx->output[1].amount = cstate->side[THEIRS].pay_msat / 1000;
/* First two outputs done, now for the HTLCs. */ /* First two outputs done, now for the HTLCs. */
total = tx->output[0].amount + tx->output[1].amount;
num = 2;
for (h = htlc_map_first(&peer->htlcs, &it); for (h = htlc_map_first(&peer->htlcs, &it);
h; h;
h = htlc_map_next(&peer->htlcs, &it)) { h = htlc_map_next(&peer->htlcs, &it)) {
if (!htlc_has(h, committed_flag)) if (!htlc_has(h, committed_flag))
continue; continue;
tx->output[num].script add_output(tx, scriptpubkey_p2wsh(tx,
= scriptpubkey_p2wsh(tx,
wscript_for_htlc(tx, peer, h, wscript_for_htlc(tx, peer, h,
rhash, side)); rhash, side)),
tx->output[num].script_length h->msatoshis / 1000, &total);
= tal_count(tx->output[num].script);
tx->output[num].amount = h->msatoshis / 1000;
total += tx->output[num++].amount;
} }
assert(num == tx->output_count);
assert(total <= peer->anchor.satoshis); assert(total <= peer->anchor.satoshis);
*map = tal_arr(ctx, int, tx->output_count); permute_outputs(tx->output, tx->output_count);
permute_outputs(tx->output, tx->output_count, *map);
remove_dust(tx, *map);
return tx; return tx;
} }

3
daemon/commit_tx.h

@ -34,6 +34,5 @@ struct bitcoin_tx *create_commit_tx(const tal_t *ctx,
struct peer *peer, struct peer *peer,
const struct sha256 *rhash, const struct sha256 *rhash,
const struct channel_state *cstate, const struct channel_state *cstate,
enum htlc_side side, enum htlc_side side);
int **map);
#endif #endif

10
daemon/peer.c

@ -782,7 +782,7 @@ static Pkt *handle_pkt_commit(struct peer *peer, const Pkt *pkt)
/* (We already applied them to staging_cstate as we went) */ /* (We already applied them to staging_cstate as we went) */
ci->cstate = copy_cstate(ci, peer->local.staging_cstate); ci->cstate = copy_cstate(ci, peer->local.staging_cstate);
ci->tx = create_commit_tx(ci, peer, &ci->revocation_hash, ci->tx = create_commit_tx(ci, peer, &ci->revocation_hash,
ci->cstate, LOCAL, &ci->map); ci->cstate, LOCAL);
bitcoin_txid(ci->tx, &ci->txid); bitcoin_txid(ci->tx, &ci->txid);
/* BOLT #2: /* BOLT #2:
@ -1539,7 +1539,7 @@ static void do_commit(struct peer *peer, struct command *jsoncmd)
* before generating `sig`. */ * before generating `sig`. */
ci->cstate = copy_cstate(ci, peer->remote.staging_cstate); ci->cstate = copy_cstate(ci, peer->remote.staging_cstate);
ci->tx = create_commit_tx(ci, peer, &ci->revocation_hash, ci->tx = create_commit_tx(ci, peer, &ci->revocation_hash,
ci->cstate, REMOTE, &ci->map); ci->cstate, REMOTE);
bitcoin_txid(ci->tx, &ci->txid); bitcoin_txid(ci->tx, &ci->txid);
log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu htlcs", log_debug(peer->log, "Signing tx for %u/%u msatoshis, %zu/%zu htlcs",
@ -3102,16 +3102,14 @@ bool setup_first_commit(struct peer *peer)
peer, peer,
&peer->local.commit->revocation_hash, &peer->local.commit->revocation_hash,
peer->local.commit->cstate, peer->local.commit->cstate,
LOCAL, LOCAL);
&peer->local.commit->map);
bitcoin_txid(peer->local.commit->tx, &peer->local.commit->txid); bitcoin_txid(peer->local.commit->tx, &peer->local.commit->txid);
peer->remote.commit->tx = create_commit_tx(peer->remote.commit, peer->remote.commit->tx = create_commit_tx(peer->remote.commit,
peer, peer,
&peer->remote.commit->revocation_hash, &peer->remote.commit->revocation_hash,
peer->remote.commit->cstate, peer->remote.commit->cstate,
REMOTE, REMOTE);
&peer->remote.commit->map);
bitcoin_txid(peer->remote.commit->tx, &peer->remote.commit->txid); bitcoin_txid(peer->remote.commit->tx, &peer->remote.commit->txid);
peer->local.staging_cstate = copy_cstate(peer, peer->local.commit->cstate); peer->local.staging_cstate = copy_cstate(peer, peer->local.commit->cstate);

2
daemon/peer.h

@ -52,8 +52,6 @@ struct commit_info {
struct channel_state *cstate; struct channel_state *cstate;
/* Other side's signature for last commit tx (if known) */ /* Other side's signature for last commit tx (if known) */
struct bitcoin_signature *sig; struct bitcoin_signature *sig;
/* Map for permutation: see commit_tx.c */
int *map;
}; };
struct peer_visible_state { struct peer_visible_state {

65
permute_tx.c

@ -2,32 +2,6 @@
#include <stdbool.h> #include <stdbool.h>
#include <string.h> #include <string.h>
static void init_map(int *map, size_t len)
{
size_t i;
if (!map)
return;
for (i = 0; i < len; i++)
map[i] = i;
}
/* This map says where things ended up, eg. 0 might be in slot 3. we
* want to change it so map[0] = 3. */
static void invert_map(int *map, size_t len)
{
if (map) {
int i, newmap[len];
memset(newmap, 0, sizeof(newmap));
for (i = 0; i < len; i++) {
newmap[map[i]] = i;
}
memcpy(map, newmap, sizeof(newmap));
}
}
static bool input_better(const struct bitcoin_tx_input *a, static bool input_better(const struct bitcoin_tx_input *a,
const struct bitcoin_tx_input *b) const struct bitcoin_tx_input *b)
{ {
@ -59,56 +33,35 @@ 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, int *map, static void swap_inputs(struct bitcoin_tx_input *inputs, size_t i1, size_t i2)
size_t i1, size_t i2)
{ {
struct bitcoin_tx_input tmpinput; struct bitcoin_tx_input tmpinput;
size_t tmpidx;
tmpinput = inputs[i1]; tmpinput = inputs[i1];
inputs[i1] = inputs[i2]; inputs[i1] = inputs[i2];
inputs[i2] = tmpinput; inputs[i2] = tmpinput;
if (map) {
tmpidx = map[i1];
map[i1] = map[i2];
map[i2] = tmpidx;
}
} }
void permute_inputs(struct bitcoin_tx_input *inputs, void permute_inputs(struct bitcoin_tx_input *inputs, size_t num_inputs)
size_t num_inputs,
int *map)
{ {
size_t i; size_t i;
init_map(map, num_inputs);
/* Now do a dumb sort (num_inputs is small). */ /* Now do a dumb sort (num_inputs is small). */
for (i = 0; i < num_inputs; i++) { for (i = 0; i < num_inputs; i++) {
/* Swap best into first place. */ /* Swap best into first place. */
swap_inputs(inputs, map, swap_inputs(inputs,
i, i + find_best_in(inputs + i, num_inputs - i)); i, i + find_best_in(inputs + i, num_inputs - i));
} }
invert_map(map, num_inputs);
} }
static void swap_outputs(struct bitcoin_tx_output *outputs, int *map, static void swap_outputs(struct bitcoin_tx_output *outputs,
size_t i1, size_t i2) size_t i1, size_t i2)
{ {
struct bitcoin_tx_output tmpoutput; struct bitcoin_tx_output tmpoutput;
size_t tmpidx;
tmpoutput = outputs[i1]; tmpoutput = outputs[i1];
outputs[i1] = outputs[i2]; outputs[i1] = outputs[i2];
outputs[i2] = tmpoutput; outputs[i2] = tmpoutput;
if (map) {
tmpidx = map[i1];
map[i1] = map[i2];
map[i2] = tmpidx;
}
} }
static bool output_better(const struct bitcoin_tx_output *a, static bool output_better(const struct bitcoin_tx_output *a,
@ -144,20 +97,14 @@ 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, void permute_outputs(struct bitcoin_tx_output *outputs, size_t num_outputs)
size_t num_outputs,
int *map)
{ {
size_t i; size_t i;
init_map(map, num_outputs);
/* 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, map, swap_outputs(outputs,
i, i + find_best_out(outputs + i, num_outputs - i)); i, i + find_best_out(outputs + i, num_outputs - i));
} }
invert_map(map, num_outputs);
} }

12
permute_tx.h

@ -3,14 +3,8 @@
#include "config.h" #include "config.h"
#include "bitcoin/tx.h" #include "bitcoin/tx.h"
/* Permute the transaction into BIP69 order. /* Permute the transaction into BIP69 order. */
* map[0] is set to the new index of input 0, etc. void permute_inputs(struct bitcoin_tx_input *inputs, size_t num_inputs);
*/
void permute_inputs(struct bitcoin_tx_input *inputs,
size_t num_inputs,
int *map);
void permute_outputs(struct bitcoin_tx_output *outputs, void permute_outputs(struct bitcoin_tx_output *outputs, size_t num_outputs);
size_t num_outputs,
int *map);
#endif /* LIGHTNING_PERMUTE_TX_H */ #endif /* LIGHTNING_PERMUTE_TX_H */

28
remove_dust.c

@ -1,28 +0,0 @@
#include "remove_dust.h"
#include <assert.h>
#include <stdbool.h>
#include <string.h>
void remove_dust(struct bitcoin_tx *tx, int *map)
{
size_t i, j, num = tx->output_count;
assert(tal_count(map) == num);
/* Do it in map order so we can remove from map, too */
for (i = 0; i < num; i++) {
assert(map[i] < tx->output_count);
if (tx->output[map[i]].amount >= DUST_THRESHOLD)
continue;
/* Eliminate that output from tx */
tx->output_count--;
memmove(tx->output + map[i], tx->output + map[i] + 1,
(tx->output_count-map[i]) * sizeof(*tx->output));
/* Fixup map. */
for (j = 0; j < num; j++)
if (map[j] > map[i])
map[j]--;
map[i] = -1;
}
}

4
remove_dust.h

@ -9,4 +9,8 @@ void remove_dust(struct bitcoin_tx *tx, int *map);
/* Less than this is dust. */ /* Less than this is dust. */
#define DUST_THRESHOLD 546 #define DUST_THRESHOLD 546
static inline bool is_dust(u64 amount)
{
return amount < DUST_THRESHOLD;
}
#endif /* LIGHTNING_REMOVE_DUST_H */ #endif /* LIGHTNING_REMOVE_DUST_H */

Loading…
Cancel
Save