mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
peer: make closing_onchain.resolved[] in tx-output order.
At the moment, for our or their unilateral close, we create a resolved[] entry for our output, their output, and each HTLC, in cstate order. Some of these outputs might not exist (too small), so it's actually better to simply keep a resolved[] entry for each of the tx's actual outputs. (We already changed the steal resolved[] array to work like this, but these are trickier, since we rely on that order if we need to fulfill an on-chain HTLC). It also helps as we are weaning off knowing the cstate and permutation mapping for each commitment transaction. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4319f3ac70
commit
2e9a039789
@ -1290,11 +1290,12 @@ static bool fulfill_onchain(struct peer *peer, struct htlc *htlc)
|
|||||||
for (i = 0; i < tal_count(ci->cstate->side[THEIRS].htlcs); i++) {
|
for (i = 0; i < tal_count(ci->cstate->side[THEIRS].htlcs); i++) {
|
||||||
if (ci->cstate->side[THEIRS].htlcs[i] == htlc) {
|
if (ci->cstate->side[THEIRS].htlcs[i] == htlc) {
|
||||||
/* Already irrevocably resolved? */
|
/* Already irrevocably resolved? */
|
||||||
if (peer->closing_onchain.resolved[i])
|
assert(ci->map[i] != -1);
|
||||||
|
if (peer->closing_onchain.resolved[ci->map[i]])
|
||||||
return false;
|
return false;
|
||||||
peer->closing_onchain.resolved[i]
|
peer->closing_onchain.resolved[ci->map[i]]
|
||||||
= htlc_fulfill_tx(peer, ci, i);
|
= htlc_fulfill_tx(peer, ci, i);
|
||||||
broadcast_tx(peer, peer->closing_onchain.resolved[i]);
|
broadcast_tx(peer, peer->closing_onchain.resolved[ci->map[i]]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2277,6 +2278,7 @@ static enum watch_result our_htlc_spent(struct peer *peer,
|
|||||||
struct sha256 sha;
|
struct sha256 sha;
|
||||||
struct rval preimage;
|
struct rval preimage;
|
||||||
size_t i = ptr2int(pi);
|
size_t i = ptr2int(pi);
|
||||||
|
const struct commit_info *ci = peer->closing_onchain.ci;
|
||||||
|
|
||||||
/* It should be spending the HTLC we expect. */
|
/* It should be spending the HTLC we expect. */
|
||||||
assert(peer->closing_onchain.ci->map[i] == tx->input[input_num].index);
|
assert(peer->closing_onchain.ci->map[i] == tx->input[input_num].index);
|
||||||
@ -2322,7 +2324,8 @@ static enum watch_result our_htlc_spent(struct peer *peer,
|
|||||||
* the redemption transaction itself once we've extracted the
|
* the redemption transaction itself once we've extracted the
|
||||||
* preimage; the knowledge is not revocable.
|
* preimage; the knowledge is not revocable.
|
||||||
*/
|
*/
|
||||||
peer->closing_onchain.resolved[i] = irrevocably_resolved(peer);
|
assert(ci->map[i] >= 0);
|
||||||
|
peer->closing_onchain.resolved[ci->map[i]] = irrevocably_resolved(peer);
|
||||||
return DELETE_WATCH;
|
return DELETE_WATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2354,6 +2357,7 @@ static enum watch_result our_htlc_depth(struct peer *peer,
|
|||||||
bool our_commit,
|
bool our_commit,
|
||||||
size_t i)
|
size_t i)
|
||||||
{
|
{
|
||||||
|
const struct commit_info *ci = peer->closing_onchain.ci;
|
||||||
struct htlc *h;
|
struct htlc *h;
|
||||||
u32 height;
|
u32 height;
|
||||||
|
|
||||||
@ -2387,14 +2391,15 @@ static enum watch_result our_htlc_depth(struct peer *peer,
|
|||||||
* MUST *resolve* the output by spending it.
|
* MUST *resolve* the output by spending it.
|
||||||
*/
|
*/
|
||||||
/* FIXME: we should simply delete this watch if HTLC is fulfilled. */
|
/* FIXME: we should simply delete this watch if HTLC is fulfilled. */
|
||||||
if (!peer->closing_onchain.resolved[i]) {
|
assert(ci->map[i] >= 0);
|
||||||
peer->closing_onchain.resolved[i]
|
if (!peer->closing_onchain.resolved[ci->map[i]]) {
|
||||||
|
peer->closing_onchain.resolved[ci->map[i]]
|
||||||
= htlc_timeout_tx(peer, peer->closing_onchain.ci, i);
|
= htlc_timeout_tx(peer, peer->closing_onchain.ci, i);
|
||||||
watch_tx(peer->closing_onchain.resolved[i],
|
watch_tx(peer->closing_onchain.resolved[ci->map[i]],
|
||||||
peer,
|
peer,
|
||||||
peer->closing_onchain.resolved[i],
|
peer->closing_onchain.resolved[ci->map[i]],
|
||||||
our_htlc_timeout_depth, int2ptr(i));
|
our_htlc_timeout_depth, int2ptr(i));
|
||||||
broadcast_tx(peer, peer->closing_onchain.resolved[i]);
|
broadcast_tx(peer, peer->closing_onchain.resolved[ci->map[i]]);
|
||||||
}
|
}
|
||||||
return DELETE_WATCH;
|
return DELETE_WATCH;
|
||||||
}
|
}
|
||||||
@ -2427,11 +2432,9 @@ static void resolve_our_htlcs(struct peer *peer,
|
|||||||
|
|
||||||
bitcoin_txid(tx, &txid);
|
bitcoin_txid(tx, &txid);
|
||||||
for (i = start; i < start + num; i++) {
|
for (i = start; i < start + num; i++) {
|
||||||
/* Doesn't exist? Resolved by tx itself. */
|
/* Doesn't exist? Ignore. */
|
||||||
if (ci->map[i] == -1) {
|
if (ci->map[i] == -1)
|
||||||
resolved[i] = tx;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
/* BOLT #onchain:
|
/* BOLT #onchain:
|
||||||
*
|
*
|
||||||
@ -2459,6 +2462,7 @@ static enum watch_result their_htlc_depth(struct peer *peer,
|
|||||||
u32 height;
|
u32 height;
|
||||||
struct htlc *h;
|
struct htlc *h;
|
||||||
size_t i = ptr2int(pi);
|
size_t i = ptr2int(pi);
|
||||||
|
const struct commit_info *ci = peer->closing_onchain.ci;
|
||||||
|
|
||||||
/* Must be in a block. */
|
/* Must be in a block. */
|
||||||
if (depth == 0)
|
if (depth == 0)
|
||||||
@ -2476,7 +2480,7 @@ static enum watch_result their_htlc_depth(struct peer *peer,
|
|||||||
if (height < abs_locktime_to_blocks(&h->expiry))
|
if (height < abs_locktime_to_blocks(&h->expiry))
|
||||||
return KEEP_WATCHING;
|
return KEEP_WATCHING;
|
||||||
|
|
||||||
peer->closing_onchain.resolved[i] = irrevocably_resolved(peer);
|
peer->closing_onchain.resolved[ci->map[i]] = irrevocably_resolved(peer);
|
||||||
return DELETE_WATCH;
|
return DELETE_WATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2491,11 +2495,9 @@ static void resolve_their_htlcs(struct peer *peer,
|
|||||||
for (i = start; i < start + num; i++) {
|
for (i = start; i < start + num; i++) {
|
||||||
struct htlc *htlc;
|
struct htlc *htlc;
|
||||||
|
|
||||||
/* Doesn't exist? Resolved by tx itself. */
|
/* Doesn't exist? Ignore. */
|
||||||
if (ci->map[i] == -1) {
|
if (ci->map[i] == -1)
|
||||||
resolved[i] = tx;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
/* BOLT #onchain:
|
/* BOLT #onchain:
|
||||||
*
|
*
|
||||||
@ -2506,9 +2508,9 @@ static void resolve_their_htlcs(struct peer *peer,
|
|||||||
*/
|
*/
|
||||||
htlc = htlc_by_index(ci, i);
|
htlc = htlc_by_index(ci, i);
|
||||||
if (htlc->r) {
|
if (htlc->r) {
|
||||||
peer->closing_onchain.resolved[i]
|
peer->closing_onchain.resolved[ci->map[i]]
|
||||||
= htlc_fulfill_tx(peer, ci, i);
|
= htlc_fulfill_tx(peer, ci, i);
|
||||||
broadcast_tx(peer, peer->closing_onchain.resolved[i]);
|
broadcast_tx(peer, peer->closing_onchain.resolved[ci->map[i]]);
|
||||||
} else {
|
} else {
|
||||||
/* BOLT #onchain:
|
/* BOLT #onchain:
|
||||||
*
|
*
|
||||||
@ -2525,11 +2527,13 @@ static enum watch_result our_main_output_depth(struct peer *peer,
|
|||||||
const struct sha256_double *txid,
|
const struct sha256_double *txid,
|
||||||
void *unused)
|
void *unused)
|
||||||
{
|
{
|
||||||
|
const struct commit_info *ci = peer->closing_onchain.ci;
|
||||||
|
|
||||||
/* Not past CSV timeout? */
|
/* Not past CSV timeout? */
|
||||||
if (depth < rel_locktime_to_blocks(&peer->remote.locktime))
|
if (depth < rel_locktime_to_blocks(&peer->remote.locktime))
|
||||||
return KEEP_WATCHING;
|
return KEEP_WATCHING;
|
||||||
|
|
||||||
assert(!peer->closing_onchain.resolved[0]);
|
assert(!peer->closing_onchain.resolved[ci->map[0]]);
|
||||||
|
|
||||||
/* BOLT #onchain:
|
/* BOLT #onchain:
|
||||||
*
|
*
|
||||||
@ -2540,8 +2544,8 @@ static enum watch_result our_main_output_depth(struct peer *peer,
|
|||||||
* recommended), the output is *resolved* by the spending
|
* recommended), the output is *resolved* by the spending
|
||||||
* transaction
|
* transaction
|
||||||
*/
|
*/
|
||||||
peer->closing_onchain.resolved[0] = bitcoin_spend_ours(peer);
|
peer->closing_onchain.resolved[ci->map[0]] = bitcoin_spend_ours(peer);
|
||||||
broadcast_tx(peer, peer->closing_onchain.resolved[0]);
|
broadcast_tx(peer, peer->closing_onchain.resolved[ci->map[0]]);
|
||||||
return DELETE_WATCH;
|
return DELETE_WATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2584,7 +2588,7 @@ static void resolve_our_unilateral(struct peer *peer,
|
|||||||
size_t num_ours, num_theirs;
|
size_t num_ours, num_theirs;
|
||||||
|
|
||||||
peer->closing_onchain.resolved
|
peer->closing_onchain.resolved
|
||||||
= tal_arrz(tx, const struct bitcoin_tx *, tal_count(ci->map));
|
= tal_arrz(tx, const struct bitcoin_tx *, tx->output_count);
|
||||||
|
|
||||||
/* This only works because we always watch for a long time before
|
/* This only works because we always watch for a long time before
|
||||||
* freeing peer, by which time this has resolved. We could create
|
* freeing peer, by which time this has resolved. We could create
|
||||||
@ -2599,6 +2603,7 @@ static void resolve_our_unilateral(struct peer *peer,
|
|||||||
* other node's `open_channel` `delay` field) before spending the
|
* other node's `open_channel` `delay` field) before spending the
|
||||||
* output.
|
* output.
|
||||||
*/
|
*/
|
||||||
|
if (ci->map[0] >= 0)
|
||||||
watch_tx(tx, peer, tx, our_main_output_depth, NULL);
|
watch_tx(tx, peer, tx, our_main_output_depth, NULL);
|
||||||
|
|
||||||
/* BOLT #onchain:
|
/* BOLT #onchain:
|
||||||
@ -2606,7 +2611,8 @@ static void resolve_our_unilateral(struct peer *peer,
|
|||||||
* 2. _B's main output_: No action required, this output is considered
|
* 2. _B's main output_: No action required, this output is considered
|
||||||
* *resolved* by the *commitment tx*.
|
* *resolved* by the *commitment tx*.
|
||||||
*/
|
*/
|
||||||
peer->closing_onchain.resolved[1] = tx;
|
if (ci->map[1] >= 0)
|
||||||
|
peer->closing_onchain.resolved[ci->map[1]] = tx;
|
||||||
|
|
||||||
num_ours = tal_count(ci->cstate->side[OURS].htlcs);
|
num_ours = tal_count(ci->cstate->side[OURS].htlcs);
|
||||||
num_theirs = tal_count(ci->cstate->side[THEIRS].htlcs);
|
num_theirs = tal_count(ci->cstate->side[THEIRS].htlcs);
|
||||||
@ -2651,7 +2657,7 @@ static void resolve_their_unilateral(struct peer *peer,
|
|||||||
|
|
||||||
ci = peer->closing_onchain.ci;
|
ci = peer->closing_onchain.ci;
|
||||||
peer->closing_onchain.resolved
|
peer->closing_onchain.resolved
|
||||||
= tal_arrz(tx, const struct bitcoin_tx *, tal_count(ci->map));
|
= tal_arrz(tx, const struct bitcoin_tx *, tx->output_count);
|
||||||
|
|
||||||
/* BOLT #onchain:
|
/* BOLT #onchain:
|
||||||
*
|
*
|
||||||
@ -2659,14 +2665,16 @@ static void resolve_their_unilateral(struct peer *peer,
|
|||||||
* simple P2WPKH output. This output is considered
|
* simple P2WPKH output. This output is considered
|
||||||
* *resolved* by the *commitment tx*.
|
* *resolved* by the *commitment tx*.
|
||||||
*/
|
*/
|
||||||
peer->closing_onchain.resolved[1] = tx;
|
if (ci->map[1] >= 0)
|
||||||
|
peer->closing_onchain.resolved[ci->map[1]] = tx;
|
||||||
|
|
||||||
/* BOLT #onchain:
|
/* BOLT #onchain:
|
||||||
*
|
*
|
||||||
* 2. _B's main output_: No action required, this output is
|
* 2. _B's main output_: No action required, this output is
|
||||||
* considered *resolved* by the *commitment tx*.
|
* considered *resolved* by the *commitment tx*.
|
||||||
*/
|
*/
|
||||||
peer->closing_onchain.resolved[0] = tx;
|
if (ci->map[0] >= 0)
|
||||||
|
peer->closing_onchain.resolved[ci->map[0]] = tx;
|
||||||
|
|
||||||
num_ours = tal_count(ci->cstate->side[OURS].htlcs);
|
num_ours = tal_count(ci->cstate->side[OURS].htlcs);
|
||||||
num_theirs = tal_count(ci->cstate->side[THEIRS].htlcs);
|
num_theirs = tal_count(ci->cstate->side[THEIRS].htlcs);
|
||||||
|
Loading…
Reference in New Issue
Block a user