diff --git a/daemon/peer.c b/daemon/peer.c index 7fe4c625f..02d97fa52 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -1792,7 +1792,7 @@ static struct peer *new_peer(struct lightningd_state *dstate, peer->commit_jsoncmd = NULL; list_head_init(&peer->outgoing_txs); list_head_init(&peer->pay_commands); - peer->anchor.watches = NULL; + peer->anchor.ok_depth = -1; peer->cur_commit.watch = NULL; peer->closing.their_sig = NULL; peer->closing.our_script = NULL; @@ -2166,30 +2166,16 @@ again: } } -struct anchor_watch { - struct peer *peer; - enum state_input depthok; - enum state_input timeout; - - /* If timeout != INPUT_NONE, this is the timer. */ - struct oneshot *timer; -}; - static enum watch_result anchor_depthchange(struct peer *peer, unsigned int depth, const struct sha256_double *txid, void *unused) { - struct anchor_watch *w = peer->anchor.watches; - /* Still waiting for it to reach depth? */ - if (w->depthok != INPUT_NONE) { - if (depth >= peer->local.mindepth) { - enum state_input in = w->depthok; - w->depthok = INPUT_NONE; - /* We don't need the timeout timer any more. */ - w->timer = tal_free(w->timer); - state_event(peer, in, NULL); + if (state_is_opening(peer->state)) { + if ((int)depth >= peer->anchor.ok_depth) { + state_event(peer, BITCOIN_ANCHOR_DEPTHOK, NULL); + peer->anchor.ok_depth = -1; } } else if (depth == 0) /* FIXME: Report losses! */ @@ -3010,8 +2996,6 @@ static enum watch_result anchor_spent(struct peer *peer, set_peer_state(peer, STATE_ERR_INFORMATION_LEAK, "anchor_spent"); - /* No longer call into the state machine. */ - peer->anchor.watches->depthok = INPUT_NONE; return DELETE_WATCH; } @@ -3037,34 +3021,28 @@ static enum watch_result anchor_spent(struct peer *peer, assert(peer->closing_onchain.resolved != NULL); watch_tx(tx, peer, tx, check_for_resolution, NULL); - /* No longer call into the state machine. */ - peer->anchor.watches->depthok = INPUT_NONE; return KEEP_WATCHING; } -static void anchor_timeout(struct anchor_watch *w) +static void anchor_timeout(struct peer *peer) { - assert(w == w->peer->anchor.watches); - state_event(w->peer, w->timeout, NULL); - - /* Freeing this gets rid of the other watches, and timer, too. */ - w->peer->anchor.watches = tal_free(w); + /* FIXME: We could just forget timeout once we're not opening. */ + if (state_is_opening(peer->state)) + state_event(peer, BITCOIN_ANCHOR_TIMEOUT, NULL); } void peer_watch_anchor(struct peer *peer, + int depth, enum state_input depthok, enum state_input timeout) { - struct anchor_watch *w; + /* We assume this. */ + assert(depthok == BITCOIN_ANCHOR_DEPTHOK); + assert(timeout == BITCOIN_ANCHOR_TIMEOUT || timeout == INPUT_NONE); - w = peer->anchor.watches = tal(peer, struct anchor_watch); - - w->peer = peer; - w->depthok = depthok; - w->timeout = timeout; - - watch_txid(w, peer, &peer->anchor.txid, anchor_depthchange, NULL); - watch_txo(w, peer, &peer->anchor.txid, 0, anchor_spent, NULL); + peer->anchor.ok_depth = depth; + watch_txid(peer, peer, &peer->anchor.txid, anchor_depthchange, NULL); + watch_txo(peer, peer, &peer->anchor.txid, 0, anchor_spent, NULL); /* For anchor timeout, expect 20 minutes per block, +2 hours. * @@ -3087,22 +3065,10 @@ void peer_watch_anchor(struct peer *peer, * * So, our formula of 12 + N*2 holds for N <= 20 at least. */ - if (w->timeout != INPUT_NONE) { - w->timer = new_reltimer(peer->dstate, w, - time_from_sec(7200 - + 20*peer->local.mindepth), - anchor_timeout, w); - } else - w->timer = NULL; -} - -void peer_unwatch_anchor_depth(struct peer *peer, - enum state_input depthok, - enum state_input timeout) -{ - assert(peer->anchor.watches); - assert(peer->anchor.watches->depthok == depthok); - peer->anchor.watches->depthok = INPUT_NONE; + if (timeout != INPUT_NONE) + new_reltimer(peer->dstate, peer, + time_from_sec(7200 + 20*peer->anchor.ok_depth), + anchor_timeout, peer); } struct bitcoin_tx *peer_create_close_tx(struct peer *peer, u64 fee) diff --git a/daemon/peer.h b/daemon/peer.h index 24e79268f..2d6a72165 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -149,7 +149,9 @@ struct peer { /* If we created it, we keep entire tx. */ const struct bitcoin_tx *tx; - struct anchor_watch *watches; + + /* Depth to trigger anchor if still opening, or -1. */ + int ok_depth; } anchor; struct { diff --git a/state.c b/state.c index ae4e2ad0c..131407508 100644 --- a/state.c +++ b/state.c @@ -156,7 +156,8 @@ enum state state(struct peer *peer, &peer->remote.commit->sig->sig); queue_pkt_open_commit_sig(peer); - peer_watch_anchor(peer, + peer_watch_anchor(peer, + peer->local.mindepth, BITCOIN_ANCHOR_DEPTHOK, BITCOIN_ANCHOR_TIMEOUT); @@ -187,6 +188,7 @@ enum state state(struct peer *peer, } queue_tx_broadcast(broadcast, bitcoin_anchor(peer)); peer_watch_anchor(peer, + peer->local.mindepth, BITCOIN_ANCHOR_DEPTHOK, INPUT_NONE); return next_state(peer, input, @@ -202,10 +204,6 @@ enum state state(struct peer *peer, err = accept_pkt_open_complete(peer, pkt); if (err) { peer_open_complete(peer, err->error->problem); - /* We no longer care about anchor depth. */ - peer_unwatch_anchor_depth(peer, - BITCOIN_ANCHOR_DEPTHOK, - INPUT_NONE); goto err_breakdown; } return next_state(peer, input, @@ -222,17 +220,9 @@ enum state state(struct peer *peer, return next_state(peer, input, STATE_OPEN_WAIT_FOR_COMPLETE_OURANCHOR); } else if (input_is(input, PKT_CLOSE_CLEARING)) { - /* We no longer care about anchor depth. */ - peer_unwatch_anchor_depth(peer, - BITCOIN_ANCHOR_DEPTHOK, - INPUT_NONE); peer_open_complete(peer, "Received PKT_CLOSE_CLEARING"); goto accept_clearing; } else if (input_is_pkt(input)) { - /* We no longer care about anchor depth. */ - peer_unwatch_anchor_depth(peer, - BITCOIN_ANCHOR_DEPTHOK, - INPUT_NONE); peer_open_complete(peer, "unexpected packet"); goto unexpected_pkt; } @@ -242,10 +232,6 @@ enum state state(struct peer *peer, err = accept_pkt_open_complete(peer, pkt); if (err) { peer_open_complete(peer, err->error->problem); - /* We no longer care about anchor depth. */ - peer_unwatch_anchor_depth(peer, - BITCOIN_ANCHOR_DEPTHOK, - BITCOIN_ANCHOR_TIMEOUT); goto err_breakdown; } return next_state(peer, input, @@ -266,17 +252,9 @@ enum state state(struct peer *peer, return next_state(peer, input, STATE_OPEN_WAIT_FOR_COMPLETE_THEIRANCHOR); } else if (input_is(input, PKT_CLOSE_CLEARING)) { - /* We no longer care about anchor depth. */ - peer_unwatch_anchor_depth(peer, - BITCOIN_ANCHOR_DEPTHOK, - BITCOIN_ANCHOR_TIMEOUT); peer_open_complete(peer, "Received PKT_CLOSE_CLEARING"); goto accept_clearing; } else if (input_is_pkt(input)) { - /* We no longer care about anchor depth. */ - peer_unwatch_anchor_depth(peer, - BITCOIN_ANCHOR_DEPTHOK, - BITCOIN_ANCHOR_TIMEOUT); peer_open_complete(peer, "unexpected packet"); goto unexpected_pkt; } diff --git a/state.h b/state.h index 495bca072..a268bb9fe 100644 --- a/state.h +++ b/state.h @@ -94,6 +94,7 @@ static inline bool input_is(enum state_input a, enum state_input b) /** * peer_watch_anchor: create a watch for the anchor transaction. * @peer: the state data for this peer. + * @depth: depth at which to fire @depthok. * @depthok: the input to give when anchor reaches expected depth. * @timeout: the input to give if anchor doesn't reach depth in time. * @@ -101,19 +102,9 @@ static inline bool input_is(enum state_input a, enum state_input b) * ourselves out). */ void peer_watch_anchor(struct peer *peer, + int depth, enum state_input depthok, enum state_input timeout); -/** - * peer_unwatch_anchor_depth: remove depth watch for the anchor. - * @peer: the state data for this peer. - * @depthok: the input to give when anchor reaches expected depth. - * @timeout: the input to give if anchor doesn't reach depth in time. - * - * @depthok and @timeout must match bitcoin_watch_anchor() call. - */ -void peer_unwatch_anchor_depth(struct peer *peer, - enum state_input depthok, - enum state_input timeout); /* Start creation of the bitcoin anchor tx. */ void bitcoin_create_anchor(struct peer *peer, enum state_input done);