mirror of
https://github.com/aljazceru/lightning.git
synced 2026-02-08 15:44:19 +01:00
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>
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
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
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);
|
||||
|
||||
Reference in New Issue
Block a user