Browse Source

peer: record depth at which anchor tx is considered deep enough.

This makes it explicit, which is better for storing in a database (before
it was just what watch callback, plus peer->local.mindepth).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
9b2fd3a969
  1. 74
      daemon/peer.c
  2. 4
      daemon/peer.h
  3. 28
      state.c
  4. 13
      state.h

74
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)

4
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 {

28
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;
}

13
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);

Loading…
Cancel
Save