diff --git a/bitcoin/script.c b/bitcoin/script.c index b0361cd4c..7e07d76e6 100644 --- a/bitcoin/script.c +++ b/bitcoin/script.c @@ -467,6 +467,17 @@ bool is_p2sh(const u8 *script, size_t script_len) return true; } +bool is_p2wsh(const u8 *script, size_t script_len) +{ + if (script_len != 1 + 1 + sizeof(struct sha256)) + return false; + if (script[0] != OP_0) + return false; + if (script[1] != OP_PUSHBYTES(sizeof(struct sha256))) + return false; + return true; +} + /* A common script pattern: A can have it with secret, or B can have * it after delay. */ u8 *bitcoin_redeem_secret_or_delay(const tal_t *ctx, diff --git a/bitcoin/script.h b/bitcoin/script.h index d3af4c867..ea677a35c 100644 --- a/bitcoin/script.h +++ b/bitcoin/script.h @@ -112,6 +112,9 @@ u8 **bitcoin_witness_htlc(const tal_t *ctx, /* Is this a pay to script hash? */ bool is_p2sh(const u8 *script, size_t script_len); +/* Is this (version 0) pay to witness script hash? */ +bool is_p2wsh(const u8 *script, size_t script_len); + /* Are these two scripts equal? */ bool scripteq(const u8 *s1, size_t s1len, const u8 *s2, size_t s2len); diff --git a/daemon/Makefile b/daemon/Makefile index a7b45b90f..f423e5530 100644 --- a/daemon/Makefile +++ b/daemon/Makefile @@ -27,6 +27,7 @@ DAEMON_SRC := \ daemon/netaddr.c \ daemon/onion.c \ daemon/opt_time.c \ + daemon/output_to_htlc.c \ daemon/packets.c \ daemon/pay.c \ daemon/payment.c \ @@ -67,6 +68,7 @@ DAEMON_HEADERS := \ daemon/netaddr.h \ daemon/onion.h \ daemon/opt_time.h \ + daemon/output_to_htlc.h \ daemon/packets.h \ daemon/pay.h \ daemon/payment.h \ diff --git a/daemon/output_to_htlc.c b/daemon/output_to_htlc.c new file mode 100644 index 000000000..265c4fa5b --- /dev/null +++ b/daemon/output_to_htlc.c @@ -0,0 +1,79 @@ +#include "commit_tx.h" +#include "output_to_htlc.h" +#include "peer.h" + +/* FIXME: Array makes this O(n^2). Use a hash table. */ +struct wscript_by_wpkh { + struct htlc *h; + const u8 *wscript; + struct sha256 hash; +}; + +struct htlc_output_map { + struct wscript_by_wpkh *wpkh; +}; + +struct htlc_output_map *get_htlc_output_map(const tal_t *ctx, + const struct peer *peer, + const struct sha256 *rhash, + enum htlc_side side, + unsigned int commit_num) +{ + struct htlc_map_iter it; + struct htlc *h; + size_t i; + struct htlc_output_map *omap = tal(ctx, struct htlc_output_map); + + /* FIXME: use commit_num to filter htlcs. */ + if (side == LOCAL) + assert(commit_num <= peer->local.commit->commit_num); + else + assert(commit_num <= peer->remote.commit->commit_num); + + omap->wpkh = tal_arr(omap, struct wscript_by_wpkh, + htlc_map_count(&peer->htlcs)); + + for (i = 0, h = htlc_map_first(&peer->htlcs, &it); + h; + h = htlc_map_next(&peer->htlcs, &it)) { + omap->wpkh[i].h = h; + omap->wpkh[i].wscript = wscript_for_htlc(omap, peer, h, rhash, + side); + sha256(&omap->wpkh[i].hash, + omap->wpkh[i].wscript, + tal_count(omap->wpkh[i].wscript)); + i++; + } + tal_resize(&omap->wpkh, i); + return omap; +} + +static struct wscript_by_wpkh *get_wpkh(struct htlc_output_map *omap, + const u8 *script, size_t script_len) +{ + size_t i; + + if (!is_p2wsh(script, script_len)) + return NULL; + + for (i = 0; i < tal_count(omap->wpkh); i++) { + if (!memcmp(script + 2, omap->wpkh[i].hash.u.u8, + sizeof(omap->wpkh[i].hash))) + return &omap->wpkh[i]; + } + return NULL; +} + +/* Which wscript does this pay to? */ +struct htlc *txout_get_htlc(struct htlc_output_map *omap, + const u8 *script, size_t script_len, + const u8 **wscript) +{ + struct wscript_by_wpkh *wpkh = get_wpkh(omap, script, script_len); + + if (wpkh) { + *wscript = wpkh->wscript; + return wpkh->h; + } + return NULL; +} diff --git a/daemon/output_to_htlc.h b/daemon/output_to_htlc.h new file mode 100644 index 000000000..7d950c53b --- /dev/null +++ b/daemon/output_to_htlc.h @@ -0,0 +1,21 @@ +#ifndef LIGHTNING_DAEMON_OUTPUT_TO_HTLC_H +#define LIGHTNING_DAEMON_OUTPUT_TO_HTLC_H +#include "config.h" +#include "htlc.h" + +struct peer; +struct sha256; + +/* Get a map of HTLCs (including at least those at the given commit_num). */ +struct htlc_output_map *get_htlc_output_map(const tal_t *ctx, + const struct peer *peer, + const struct sha256 *rhash, + enum htlc_side side, + unsigned int commit_num); + +/* If this scriptPubkey pays to a HTLC, get the full wscript */ +struct htlc *txout_get_htlc(struct htlc_output_map *omap, + const u8 *script, size_t script_len, + const u8 **wscript); + +#endif /* LIGHTNING_DAEMON_OUTPUT_TO_HTLC_H */ diff --git a/daemon/peer.c b/daemon/peer.c index 5ebede06c..4b7486ab3 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -11,6 +11,7 @@ #include "log.h" #include "names.h" #include "onion.h" +#include "output_to_htlc.h" #include "packets.h" #include "pay.h" #include "payment.h" @@ -1324,14 +1325,6 @@ static struct htlc *htlc_by_index(const struct commit_info *ci, size_t index) return ci->cstate->side[THEIRS].htlcs[index]; } -static bool htlc_is_ours(const struct commit_info *ci, size_t index) -{ - assert(index >= 2); - index -= 2; - - return index < tal_count(ci->cstate->side[OURS].htlcs); -} - /* Create a HTLC fulfill transaction */ static const struct bitcoin_tx *htlc_fulfill_tx(const struct peer *peer, const struct commit_info *ci, @@ -2198,16 +2191,77 @@ static enum watch_result anchor_depthchange(struct peer *peer, return KEEP_WATCHING; } -static struct commit_info *find_commit(struct commit_info *ci, - const struct sha256_double *txid) +static bool outputscript_eq(const struct bitcoin_tx_output *out, + size_t i, const u8 *script) { - while (ci) { - /* Yay, segwit! We can just compare txids, even - * though we don't have both signatures. */ - if (structeq(txid, &ci->txid)) - return ci; - ci = ci->prev; + if (out[i].script_length != tal_count(script)) + return false; + return memcmp(out[i].script, script, out[i].script_length) == 0; +} + +/* This tx is their commitment; htlcs array points to NULL (in which case, it's + * to_them_idx or to_us_idx) or a valid HTLC. */ +static struct htlc **tx_map_outputs(const struct peer *peer, + const struct sha256 *rhash, + const struct bitcoin_tx *tx, + enum htlc_side side, + unsigned int commit_num, + int *to_us_idx, int *to_them_idx, + const u8 ***wscripts) +{ + u8 *to_us, *to_them, *to_them_wscript, *to_us_wscript; + struct htlc_output_map *hmap; + tal_t *tmpctx = tal(peer, char); + struct htlc **htlcs; + size_t i; + + *to_us_idx = *to_them_idx = -1; + htlcs = tal_arr(tmpctx, struct htlc *, tx->output_count); + *wscripts = tal_arr(tmpctx, const u8 *, tx->output_count); + + to_us = commit_output_to_us(tmpctx, peer, rhash, side, &to_us_wscript); + to_them = commit_output_to_them(tmpctx, peer, rhash, side, + &to_them_wscript); + + /* Now generate the wscript hashes for every possible HTLC. */ + hmap = get_htlc_output_map(tmpctx, peer, rhash, side, commit_num); + + for (i = 0; i < tx->output_count; i++) { + log_debug(peer->log, "%s: output %zi", __func__, i); + if (*to_us_idx == -1 && outputscript_eq(tx->output, i, to_us)) { + log_add(peer->log, " -> to us"); + htlcs[i] = NULL; + (*wscripts)[i] = tal_steal(*wscripts, to_us_wscript); + *to_us_idx = i; + continue; + } + if (*to_them_idx == -1 && outputscript_eq(tx->output, i, to_them)) { + log_add(peer->log, " -> to them"); + htlcs[i] = NULL; + (*wscripts)[i] = tal_steal(*wscripts, to_them_wscript); + *to_them_idx = i; + continue; + } + /* Must be an HTLC output */ + htlcs[i] = txout_get_htlc(hmap, + tx->output[i].script, + tx->output[i].script_length, + wscripts[i]); + if (!htlcs[i]) { + log_add(peer->log, "no HTLC found"); + goto fail; + } + tal_steal(htlcs, htlcs[i]); + tal_steal(*wscripts, *wscripts[i]); + log_add(peer->log, "HTLC %"PRIu64, htlcs[i]->id); } + tal_steal(peer, htlcs); + tal_steal(peer, *wscripts); + tal_free(tmpctx); + return htlcs; + +fail: + tal_free(tmpctx); return NULL; } @@ -2327,149 +2381,6 @@ static const struct bitcoin_tx *irrevocably_resolved(struct peer *peer) return peer->closing_onchain.tx; } -static void connect_input(const struct commit_info *ci, - struct bitcoin_tx_input *input, - u32 index) -{ - bitcoin_txid(ci->tx, &input->txid); - input->index = index; - input->amount = tal_dup(ci, u64, &ci->tx->output[index].amount); -} - -static void resolve_cheating(struct peer *peer) -{ - const struct bitcoin_tx *tx = peer->closing_onchain.tx; - const struct commit_info *ci = peer->closing_onchain.ci; - struct bitcoin_tx *steal_tx; - u8 **wscripts; - size_t i, n, num_to_steal; - int *map; - - peer->closing_onchain.resolved - = tal_arrz(tx, const struct bitcoin_tx *, tal_count(ci->map)); - - /* BOLT #onchain: - * - * If a node sees a *commitment tx* for which it has a revocation - * preimage, it *resolves* the funding transaction output: - * - * 1. _A's main output_: No action is required; this is a - * simple P2WPKH output. This output is considered - * *resolved* by the *commitment tx*. - */ - - /* Their commit tx, so our output is [1], theirs in [0]. */ - peer->closing_onchain.resolved[1] = tx; - - /* BOLT #onchain: - * - * 2. _B's main output_: The node MUST *resolve* this by - * spending using the revocation preimage. - * - * 3. _A's offered HTLCs_: The node MUST *resolve* this by - * spending using the revocation preimage. - * - * 4. _B's offered HTLCs_: The node MUST *resolve* this by - * spending using the revocation preimage. */ - num_to_steal = 0; - if (ci->map[0] == -1) - peer->closing_onchain.resolved[0] = tx; - else - num_to_steal++; - - for (i = 2; i < tal_count(ci->map); i++) - if (ci->map[i] == -1) - peer->closing_onchain.resolved[i] = tx; - else - num_to_steal++; - - /* Nothing to steal? */ - if (num_to_steal == 0) - return; - - /* BOLT #onchain: - * - * The node MAY use a single transaction to *resolve* all the - * outputs; due to the 300 HTLC-per-party limit (See BOLT #2: - * 3.2. Adding an HTLC) this can be done within a standard - * transaction. - */ - steal_tx = bitcoin_tx(peer, num_to_steal, 1); - - wscripts = tal_arr(steal_tx, u8 *, num_to_steal); - - n = 0; - if (ci->map[0] != -1) { - connect_input(ci, &steal_tx->input[n], ci->map[0]); - peer->closing_onchain.resolved[0] = steal_tx; - wscripts[n++] - = bitcoin_redeem_secret_or_delay(wscripts, - peer->dstate->secpctx, - &peer->remote.finalkey, - &peer->local.locktime, - &peer->local.finalkey, - &ci->revocation_hash); - } - - for (i = 2; i < tal_count(ci->map); i++) { - struct htlc *h; - - if (ci->map[i] == -1) - continue; - - peer->closing_onchain.resolved[i] = steal_tx; - - connect_input(ci, &steal_tx->input[n], ci->map[i]); - - h = htlc_by_index(ci, i); - if (!htlc_is_ours(ci, i)) { - wscripts[n] - = bitcoin_redeem_htlc_send(wscripts, - peer->dstate->secpctx, - &peer->remote.finalkey, - &peer->local.finalkey, - &h->expiry, - &peer->local.locktime, - &ci->revocation_hash, - &h->rhash); - } else { - wscripts[n] - = bitcoin_redeem_htlc_recv(wscripts, - peer->dstate->secpctx, - &peer->remote.finalkey, - &peer->local.finalkey, - &h->expiry, - &peer->local.locktime, - &ci->revocation_hash, - &h->rhash); - } - n++; - } - assert(n == num_to_steal); - - /* This obscures the order in which HTLCs were received, at least. */ - map = tal_arr(steal_tx, int, num_to_steal); - permute_inputs(steal_tx->input, steal_tx->input_count, map); - - /* Now, we can sign them all (they're all of same form). */ - for (n = 0; n < num_to_steal; n++) { - struct bitcoin_signature sig; - - sig.stype = SIGHASH_ALL; - peer_sign_steal_input(peer, steal_tx, map[n], wscripts[n], &sig.sig); - - steal_tx->input[map[n]].witness - = bitcoin_witness_secret(steal_tx, - peer->dstate->secpctx, - ci->revocation_preimage, - sizeof(*ci->revocation_preimage), - &sig, - wscripts[n]); - } - - broadcast_tx(peer, steal_tx); -} - static enum watch_result our_htlc_spent(struct peer *peer, const struct bitcoin_tx *tx, size_t input_num, @@ -2772,9 +2683,9 @@ static enum watch_result our_unilateral_depth(struct peer *peer, * * When node A sees its own *commitment tx*: */ -static void resolve_our_unilateral(struct peer *peer) +static void resolve_our_unilateral(struct peer *peer, + const struct bitcoin_tx *tx) { - const struct bitcoin_tx *tx = peer->closing_onchain.tx; const struct commit_info *ci = peer->closing_onchain.ci; size_t num_ours, num_theirs; @@ -2828,9 +2739,9 @@ static void resolve_our_unilateral(struct peer *peer) * * Similarly, when node A sees a *commitment tx* from B: */ -static void resolve_their_unilateral(struct peer *peer) +static void resolve_their_unilateral(struct peer *peer, + const struct bitcoin_tx *tx) { - const struct bitcoin_tx *tx = peer->closing_onchain.tx; const struct commit_info *ci = peer->closing_onchain.ci; size_t num_ours, num_theirs; @@ -2939,7 +2850,151 @@ static enum watch_result check_for_resolution(struct peer *peer, return DELETE_WATCH; } - + +static bool find_their_old_tx(struct peer *peer, + const struct sha256_double *txid, + u64 *idx) +{ + /* FIXME: Don't keep these in memory, search db here. */ + struct their_commit *tc; + + log_debug_struct(peer->log, "Finding txid %s", struct sha256_double, + txid); + list_for_each(&peer->their_commits, tc, list) { + if (structeq(&tc->txid, txid)) { + *idx = tc->commit_num; + return true; + } + } + return false; +} + +static bool resolve_their_steal(struct peer *peer, + const struct bitcoin_tx *tx) +{ + u64 commit_num; + struct sha256_double txid; + struct sha256 revocation_preimage, rhash; + int to_us_idx, to_them_idx, i, n; + struct htlc **htlcs; + const u8 **wscripts; + struct bitcoin_tx *steal_tx; + size_t wsize = 0; + u64 input_total = 0, fee; + + bitcoin_txid(tx, &txid); + if (!find_their_old_tx(peer, &txid, &commit_num)) { + log_broken_struct(peer->log, "Could not find revoked txid %s", + struct sha256_double, &txid); + return false; + } + + if (!shachain_get_hash(&peer->their_preimages, + 0xFFFFFFFFFFFFFFFFL - commit_num, + &revocation_preimage)) { + log_broken(peer->log, "Could not get shachain for %"PRIu64, + commit_num); + return false; + } + sha256(&rhash, &revocation_preimage, sizeof(revocation_preimage)); + + htlcs = tx_map_outputs(peer, &rhash, tx, REMOTE, commit_num, + &to_us_idx, &to_them_idx, &wscripts); + if (!htlcs) { + log_broken(peer->log, "Could not map_htlcs for %"PRIu64, + commit_num); + return false; + } + + /* FIXME: Caller should allocate this. */ + peer->closing_onchain.resolved + = tal_arr(tx, const struct bitcoin_tx *, tx->output_count); + + /* Create steal_tx: don't need to steal to_us output */ + if (to_us_idx == -1) + steal_tx = bitcoin_tx(tx, tx->output_count, 1); + else + steal_tx = bitcoin_tx(tx, tx->output_count - 1, 1); + n = 0; + + log_debug(peer->log, "Analyzing tx to steal:"); + for (i = 0; i < tx->output_count; i++) { + /* BOLT #onchain: + * 1. _A's main output_: No action is required; this is a + * simple P2WPKH output. This output is considered + * *resolved* by the *commitment tx*. + */ + if (i == to_us_idx) { + log_debug(peer->log, "%i is to-us, ignoring", i); + peer->closing_onchain.resolved[i] = tx; + continue; + } + + /* BOLT #onchain: + * + * 2. _B's main output_: The node MUST *resolve* this by + * spending using the revocation preimage. + * + * 3. _A's offered HTLCs_: The node MUST *resolve* this by + * spending using the revocation preimage. + * + * 4. _B's offered HTLCs_: The node MUST *resolve* this by + * spending using the revocation preimage. + */ + peer->closing_onchain.resolved[i] = steal_tx; + + /* Connect it up. */ + steal_tx->input[n].txid = txid; + steal_tx->input[n].index = i; + steal_tx->input[n].amount = tal_dup(steal_tx, u64, + &tx->output[i].amount); + /* Track witness size, for fee. */ + wsize += tal_count(wscripts[n]); + input_total += tx->output[i].amount; + n++; + } + assert(n == steal_tx->input_count); + + /* FIXME: Dynamic fees! */ + fee = peer->dstate->config.closing_fee_rate + * (measure_tx_cost(steal_tx) + wsize) / 1000; + + if (fee > input_total || is_dust_amount(input_total - fee)) { + log_unusual(peer->log, "Not worth stealing tiny amount %"PRIu64, + input_total); + /* Consider them all resolved by steal tx. */ + for (i = 0; i < tal_count(peer->closing_onchain.resolved); i++) + peer->closing_onchain.resolved[i] = tx; + tal_free(steal_tx); + return true; + } + steal_tx->output[0].amount = input_total - fee; + steal_tx->output[0].script = scriptpubkey_p2sh(steal_tx, + bitcoin_redeem_single(steal_tx, + peer->dstate->secpctx, + &peer->local.finalkey)); + steal_tx->output[0].script_length = tal_count(steal_tx->output[0].script); + + /* Now, we can sign them all (they're all of same form). */ + for (i = 0; i < n; i++) { + struct bitcoin_signature sig; + + sig.stype = SIGHASH_ALL; + peer_sign_steal_input(peer, steal_tx, i, wscripts[i], &sig.sig); + + steal_tx->input[i].witness + = bitcoin_witness_secret(steal_tx, + peer->dstate->secpctx, + &revocation_preimage, + sizeof(revocation_preimage), + &sig, + wscripts[i]); + } + + broadcast_tx(peer, steal_tx); + return true; +} + /* We assume the tx is valid! Don't do a blockchain.info and feed this * invalid transactions! */ static enum watch_result anchor_spent(struct peer *peer, @@ -2950,13 +3005,16 @@ static enum watch_result anchor_spent(struct peer *peer, struct sha256_double txid; Pkt *err; enum state newstate; - size_t i; + struct htlc_map_iter it; + struct htlc *h; assert(input_num < tx->input_count); /* We only ever sign single-input txs. */ - if (input_num != 0) - fatal("Anchor spend by non-single input tx"); + if (input_num != 0) { + log_broken(peer->log, "Anchor spend by non-single input tx"); + goto unknown_spend; + } /* We may have been following a different spend. Forget it. */ reset_onchain_closing(peer); @@ -2965,50 +3023,47 @@ static enum watch_result anchor_spent(struct peer *peer, bitcoin_txid(tx, &txid); /* If we have any HTLCs we're not committed to yet, fail them now. */ - for (i = 0; i < tal_count(peer->remote.commit->unacked_changes); i++) { - if (peer->remote.commit->unacked_changes[i].type != HTLC_ADD) - continue; - our_htlc_failed(peer, - peer->remote.commit->unacked_changes[i].add.htlc); + for (h = htlc_map_first(&peer->htlcs, &it); + h; + h = htlc_map_next(&peer->htlcs, &it)) { + if (h->state == SENT_ADD_HTLC) { + our_htlc_failed(peer, h); + } } - peer->closing_onchain.ci = find_commit(peer->remote.commit, &txid); - if (peer->closing_onchain.ci) { - if (peer->closing_onchain.ci->revocation_preimage) { - newstate = STATE_CLOSE_ONCHAIN_CHEATED; - err = pkt_err(peer, "Revoked transaction seen"); - resolve_cheating(peer); - } else { - newstate = STATE_CLOSE_ONCHAIN_THEIR_UNILATERAL; - err = pkt_err(peer, "Unilateral close tx seen"); - resolve_their_unilateral(peer); - } + /* A mutual close tx. */ + if (is_mutual_close(peer, tx)) { + newstate = STATE_CLOSE_ONCHAIN_MUTUAL; + err = NULL; + resolve_mutual_close(peer); + /* Our unilateral */ } else if (structeq(&peer->local.commit->txid, &txid)) { newstate = STATE_CLOSE_ONCHAIN_OUR_UNILATERAL; /* We're almost certainly closed to them by now. */ err = pkt_err(peer, "Our own unilateral close tx seen"); peer->closing_onchain.ci = peer->local.commit; - resolve_our_unilateral(peer); - } else if (is_mutual_close(peer, tx)) { - newstate = STATE_CLOSE_ONCHAIN_MUTUAL; - err = NULL; - resolve_mutual_close(peer); + resolve_our_unilateral(peer, tx); + /* Their unilateral */ + } else if (structeq(&peer->remote.commit->txid, &txid)) { + newstate = STATE_CLOSE_ONCHAIN_THEIR_UNILATERAL; + peer->closing_onchain.ci = peer->remote.commit; + err = pkt_err(peer, "Unilateral close tx seen"); + resolve_their_unilateral(peer, tx); + /* Their previous, unrevoked unilateral */ + } else if (peer->remote.commit->prev + && !peer->remote.commit->prev->revocation_preimage + && structeq(&peer->remote.commit->prev->txid, &txid)) { + newstate = STATE_CLOSE_ONCHAIN_THEIR_UNILATERAL; + peer->closing_onchain.ci = peer->remote.commit->prev; + err = pkt_err(peer, "Unilateral close tx seen"); + resolve_their_unilateral(peer, tx); + } else if (resolve_their_steal(peer, tx)) { + newstate = STATE_CLOSE_ONCHAIN_CHEATED; + err = pkt_err(peer, "Revoked transaction seen"); } else { - /* BOLT #onchain: - * - * A node SHOULD report an error to the operator if it - * sees a transaction spend the funding transaction - * output which does not fall into one of these - * categories (mutual close, unilateral close, or - * cheating attempt). Such a transaction implies its - * private key has leaked, and funds may be lost. - */ /* FIXME: Log harder! */ - log_broken(peer->log, "Unknown tx spend! Funds may be lost!"); - set_peer_state(peer, - STATE_ERR_INFORMATION_LEAK, - "anchor_spent"); - return DELETE_WATCH; + log_broken(peer->log, "Unknown anchor spend! Funds may be lost!"); + goto unknown_spend; } /* BOLT #onchain: @@ -3034,6 +3089,19 @@ static enum watch_result anchor_spent(struct peer *peer, watch_tx(tx, peer, tx, check_for_resolution, NULL); return KEEP_WATCHING; + +unknown_spend: + /* BOLT #onchain: + * + * A node SHOULD report an error to the operator if it + * sees a transaction spend the funding transaction + * output which does not fall into one of these + * categories (mutual close, unilateral close, or + * cheating attempt). Such a transaction implies its + * private key has leaked, and funds may be lost. + */ + set_peer_state(peer, STATE_ERR_INFORMATION_LEAK, "anchor_spent"); + return DELETE_WATCH; } static void anchor_timeout(struct peer *peer) diff --git a/daemon/peer.h b/daemon/peer.h index d2d2eeb37..1b3404788 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -195,6 +195,8 @@ struct peer { struct { /* Everything (watches, resolved[], etc) tal'ed off this */ const struct bitcoin_tx *tx; + /* Set for STATE_CLOSE_ONCHAIN_THEIR_UNILATERAL + * and STATE_CLOSE_ONCHAIN_OUR_UNILATERAL */ const struct commit_info *ci; const struct bitcoin_tx **resolved; } closing_onchain;