|
@ -6,21 +6,20 @@ |
|
|
#include "channel.h" |
|
|
#include "channel.h" |
|
|
#include "commit_tx.h" |
|
|
#include "commit_tx.h" |
|
|
#include "htlc.h" |
|
|
#include "htlc.h" |
|
|
|
|
|
#include "lightningd.h" |
|
|
#include "overflows.h" |
|
|
#include "overflows.h" |
|
|
|
|
|
#include "peer.h" |
|
|
#include "permute_tx.h" |
|
|
#include "permute_tx.h" |
|
|
#include "remove_dust.h" |
|
|
#include "remove_dust.h" |
|
|
#include <assert.h> |
|
|
#include <assert.h> |
|
|
|
|
|
|
|
|
u8 *wscript_for_htlc(const tal_t *ctx, |
|
|
u8 *wscript_for_htlc(const tal_t *ctx, |
|
|
secp256k1_context *secpctx, |
|
|
const struct peer *peer, |
|
|
const struct htlc *h, |
|
|
const struct htlc *h, |
|
|
const struct pubkey *our_final, |
|
|
|
|
|
const struct pubkey *their_final, |
|
|
|
|
|
const struct rel_locktime *our_locktime, |
|
|
|
|
|
const struct rel_locktime *their_locktime, |
|
|
|
|
|
const struct sha256 *rhash, |
|
|
const struct sha256 *rhash, |
|
|
enum htlc_side side) |
|
|
enum htlc_side side) |
|
|
{ |
|
|
{ |
|
|
|
|
|
const struct peer_visible_state *this_side, *other_side; |
|
|
u8 *(*fn)(const tal_t *, secp256k1_context *, |
|
|
u8 *(*fn)(const tal_t *, secp256k1_context *, |
|
|
const struct pubkey *, const struct pubkey *, |
|
|
const struct pubkey *, const struct pubkey *, |
|
|
const struct abs_locktime *, const struct rel_locktime *, |
|
|
const struct abs_locktime *, const struct rel_locktime *, |
|
@ -32,107 +31,108 @@ u8 *wscript_for_htlc(const tal_t *ctx, |
|
|
else |
|
|
else |
|
|
fn = bitcoin_redeem_htlc_recv; |
|
|
fn = bitcoin_redeem_htlc_recv; |
|
|
|
|
|
|
|
|
if (side == LOCAL) |
|
|
if (side == LOCAL) { |
|
|
return fn(ctx, secpctx, our_final, their_final, |
|
|
this_side = &peer->local; |
|
|
&h->expiry, our_locktime, rhash, &h->rhash); |
|
|
other_side = &peer->remote; |
|
|
else |
|
|
} else { |
|
|
return fn(ctx, secpctx, their_final, our_final, |
|
|
this_side = &peer->remote; |
|
|
&h->expiry, their_locktime, rhash, &h->rhash); |
|
|
other_side = &peer->local; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return fn(ctx, peer->dstate->secpctx, |
|
|
|
|
|
&this_side->finalkey, &other_side->finalkey, |
|
|
|
|
|
&h->expiry, &this_side->locktime, rhash, &h->rhash); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static size_t count_htlcs(const struct htlc_map *htlcs, int flag) |
|
|
|
|
|
{ |
|
|
|
|
|
struct htlc_map_iter it; |
|
|
|
|
|
struct htlc *h; |
|
|
|
|
|
size_t n = 0; |
|
|
|
|
|
|
|
|
|
|
|
for (h = htlc_map_first(htlcs, &it); h; h = htlc_map_next(htlcs, &it)) { |
|
|
|
|
|
if (htlc_has(h, flag)) |
|
|
|
|
|
n++; |
|
|
|
|
|
} |
|
|
|
|
|
return n; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
struct bitcoin_tx *create_commit_tx(const tal_t *ctx, |
|
|
struct bitcoin_tx *create_commit_tx(const tal_t *ctx, |
|
|
secp256k1_context *secpctx, |
|
|
struct peer *peer, |
|
|
const struct pubkey *our_final, |
|
|
|
|
|
const struct pubkey *their_final, |
|
|
|
|
|
const struct rel_locktime *our_locktime, |
|
|
|
|
|
const struct rel_locktime *their_locktime, |
|
|
|
|
|
const struct sha256_double *anchor_txid, |
|
|
|
|
|
unsigned int anchor_index, |
|
|
|
|
|
u64 anchor_satoshis, |
|
|
|
|
|
const struct sha256 *rhash, |
|
|
const struct sha256 *rhash, |
|
|
const struct channel_state *cstate, |
|
|
const struct channel_state *cstate, |
|
|
enum channel_side side, |
|
|
enum htlc_side side, |
|
|
int **map) |
|
|
int **map) |
|
|
{ |
|
|
{ |
|
|
struct bitcoin_tx *tx; |
|
|
struct bitcoin_tx *tx; |
|
|
const u8 *redeemscript; |
|
|
const u8 *redeemscript; |
|
|
size_t i, num; |
|
|
size_t num; |
|
|
uint64_t total; |
|
|
uint64_t total; |
|
|
const struct pubkey *self, *other; |
|
|
const struct pubkey *self, *other; |
|
|
const struct rel_locktime *locktime; |
|
|
const struct rel_locktime *locktime; |
|
|
enum htlc_side htlc_side; |
|
|
struct htlc_map_iter it; |
|
|
|
|
|
struct htlc *h; |
|
|
|
|
|
enum channel_side channel_side; |
|
|
|
|
|
int committed_flag = HTLC_FLAG(side,HTLC_F_COMMITTED); |
|
|
|
|
|
|
|
|
/* Now create commitment tx: one input, two outputs (plus htlcs) */ |
|
|
/* Now create commitment tx: one input, two outputs (plus htlcs) */ |
|
|
tx = bitcoin_tx(ctx, 1, 2 + tal_count(cstate->side[OURS].htlcs) |
|
|
tx = bitcoin_tx(ctx, 1, 2 + count_htlcs(&peer->htlcs, committed_flag)); |
|
|
+ tal_count(cstate->side[THEIRS].htlcs)); |
|
|
|
|
|
|
|
|
|
|
|
/* Our input spends the anchor tx output. */ |
|
|
/* Our input spends the anchor tx output. */ |
|
|
tx->input[0].txid = *anchor_txid; |
|
|
tx->input[0].txid = peer->anchor.txid; |
|
|
tx->input[0].index = anchor_index; |
|
|
tx->input[0].index = peer->anchor.index; |
|
|
tx->input[0].amount = tal_dup(tx->input, u64, &anchor_satoshis); |
|
|
tx->input[0].amount = tal_dup(tx->input, u64, &peer->anchor.satoshis); |
|
|
|
|
|
|
|
|
/* For our commit tx, our payment is delayed by amount they said */ |
|
|
/* For our commit tx, our payment is delayed by amount they said */ |
|
|
if (side == OURS) { |
|
|
if (side == LOCAL) { |
|
|
htlc_side = LOCAL; |
|
|
channel_side = OURS; |
|
|
self = our_final; |
|
|
self = &peer->local.finalkey; |
|
|
other = their_final; |
|
|
other = &peer->remote.finalkey; |
|
|
locktime = their_locktime; |
|
|
locktime = &peer->remote.locktime; |
|
|
} else { |
|
|
} else { |
|
|
htlc_side = REMOTE; |
|
|
channel_side = THEIRS; |
|
|
self = their_final; |
|
|
self = &peer->remote.finalkey; |
|
|
other = our_final; |
|
|
other = &peer->local.finalkey; |
|
|
locktime = our_locktime; |
|
|
locktime = &peer->local.locktime; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* First output is a P2WSH to a complex redeem script
|
|
|
/* First output is a P2WSH to a complex redeem script
|
|
|
* (usu. for this side) */ |
|
|
* (usu. for this side) */ |
|
|
redeemscript = bitcoin_redeem_secret_or_delay(tx, secpctx, self, |
|
|
redeemscript = bitcoin_redeem_secret_or_delay(tx, peer->dstate->secpctx, |
|
|
|
|
|
self, |
|
|
locktime, |
|
|
locktime, |
|
|
other, |
|
|
other, |
|
|
rhash); |
|
|
rhash); |
|
|
tx->output[0].script = scriptpubkey_p2wsh(tx, redeemscript); |
|
|
tx->output[0].script = scriptpubkey_p2wsh(tx, redeemscript); |
|
|
tx->output[0].script_length = tal_count(tx->output[0].script); |
|
|
tx->output[0].script_length = tal_count(tx->output[0].script); |
|
|
tx->output[0].amount = cstate->side[side].pay_msat / 1000; |
|
|
tx->output[0].amount = cstate->side[channel_side].pay_msat / 1000; |
|
|
|
|
|
|
|
|
/* Second output is a P2WPKH payment to other side. */ |
|
|
/* Second output is a P2WPKH payment to other side. */ |
|
|
tx->output[1].script = scriptpubkey_p2wpkh(tx, secpctx, other); |
|
|
tx->output[1].script = scriptpubkey_p2wpkh(tx, peer->dstate->secpctx, |
|
|
|
|
|
other); |
|
|
tx->output[1].script_length = tal_count(tx->output[1].script); |
|
|
tx->output[1].script_length = tal_count(tx->output[1].script); |
|
|
tx->output[1].amount = cstate->side[!side].pay_msat / 1000; |
|
|
tx->output[1].amount = cstate->side[!channel_side].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; |
|
|
total = tx->output[0].amount + tx->output[1].amount; |
|
|
num = 2; |
|
|
num = 2; |
|
|
|
|
|
|
|
|
for (i = 0; i < tal_count(cstate->side[side].htlcs); i++) { |
|
|
for (h = htlc_map_first(&peer->htlcs, &it); |
|
|
tx->output[num].script |
|
|
h; |
|
|
= scriptpubkey_p2wsh(tx, |
|
|
h = htlc_map_next(&peer->htlcs, &it)) { |
|
|
wscript_for_htlc(tx, secpctx, |
|
|
if (!htlc_has(h, committed_flag)) |
|
|
cstate->side[side].htlcs[i], |
|
|
continue; |
|
|
our_final, their_final, |
|
|
|
|
|
our_locktime, their_locktime, |
|
|
|
|
|
rhash, htlc_side)); |
|
|
|
|
|
tx->output[num].script_length |
|
|
|
|
|
= tal_count(tx->output[num].script); |
|
|
|
|
|
tx->output[num].amount |
|
|
|
|
|
= cstate->side[side].htlcs[i]->msatoshis / 1000; |
|
|
|
|
|
total += tx->output[num++].amount; |
|
|
|
|
|
} |
|
|
|
|
|
for (i = 0; i < tal_count(cstate->side[!side].htlcs); i++) { |
|
|
|
|
|
tx->output[num].script |
|
|
tx->output[num].script |
|
|
= scriptpubkey_p2wsh(tx, |
|
|
= scriptpubkey_p2wsh(tx, |
|
|
wscript_for_htlc(tx, secpctx, |
|
|
wscript_for_htlc(tx, peer, h, |
|
|
cstate->side[!side].htlcs[i], |
|
|
rhash, side)); |
|
|
our_final, their_final, |
|
|
|
|
|
our_locktime, their_locktime, |
|
|
|
|
|
rhash, htlc_side)); |
|
|
|
|
|
tx->output[num].script_length |
|
|
tx->output[num].script_length |
|
|
= tal_count(tx->output[num].script); |
|
|
= tal_count(tx->output[num].script); |
|
|
tx->output[num].amount |
|
|
tx->output[num].amount = h->msatoshis / 1000; |
|
|
= cstate->side[!side].htlcs[i]->msatoshis / 1000; |
|
|
|
|
|
total += tx->output[num++].amount; |
|
|
total += tx->output[num++].amount; |
|
|
} |
|
|
} |
|
|
assert(num == tx->output_count); |
|
|
assert(num == tx->output_count); |
|
|
assert(total <= anchor_satoshis); |
|
|
assert(total <= peer->anchor.satoshis); |
|
|
|
|
|
|
|
|
*map = tal_arr(ctx, int, tx->output_count); |
|
|
*map = tal_arr(ctx, int, tx->output_count); |
|
|
permute_outputs(tx->output, tx->output_count, *map); |
|
|
permute_outputs(tx->output, tx->output_count, *map); |
|
|