From 1b41335121cd0fded919d10a9507ef1cf1b8a734 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Wed, 3 Jan 2018 15:56:44 +1030 Subject: [PATCH] chain_topology: two-stage startup. Load the first block we're possibly interested in, then load the peers so we can restore the tx watches, then finally replay to the current tip. Signed-off-by: Rusty Russell --- lightningd/chaintopology.c | 18 ++++++++--------- lightningd/chaintopology.h | 2 ++ lightningd/lightningd.c | 6 ++++++ lightningd/peer_control.c | 32 ++++++++++++++++++++++++++++++ lightningd/peer_control.h | 3 +++ lightningd/test/run-find_my_path.c | 6 ++++++ 6 files changed, 58 insertions(+), 9 deletions(-) diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index b744852cb..0999f31f1 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -22,10 +22,6 @@ static void try_extend_tip(struct chain_topology *topo); static void next_topology_timer(struct chain_topology *topo) { - if (topo->startup) { - topo->startup = false; - io_break(topo); - } /* This takes care of its own lifetime. */ notleak(new_reltimer(topo->timers, topo, topo->poll_time, try_extend_tip, topo)); @@ -216,7 +212,8 @@ static void destroy_outgoing_tx(struct outgoing_tx *otx) static void clear_otx_peer(struct peer *peer, struct outgoing_tx *otx) { - assert(otx->peer == peer); + if (otx->peer != peer) + fatal("peer %p, otx %p has peer %p", peer, otx, otx->peer); otx->peer = NULL; } @@ -454,7 +451,7 @@ static void init_topo(struct bitcoind *bitcoind, block_map_add(&topo->block_map, topo->root); topo->tip = topo->prev_tip = topo->root; - try_extend_tip(topo); + io_break(topo); } static void get_init_block(struct bitcoind *bitcoind, @@ -710,7 +707,6 @@ void setup_topology(struct chain_topology *topo, struct timers *timers, struct timerel poll_time, u32 first_peer_block) { - topo->startup = true; memset(&topo->feerate, 0, sizeof(topo->feerate)); topo->timers = timers; topo->poll_time = poll_time; @@ -728,7 +724,11 @@ void setup_topology(struct chain_topology *topo, /* Begin fee estimation. */ start_fee_estimate(topo); - /* Once it gets topology, it calls io_break() and we return. */ + /* Once it gets initial block, it calls io_break() and we return. */ io_loop(NULL, NULL); - assert(!topo->startup); +} + +void begin_topology(struct chain_topology *topo) +{ + try_extend_tip(topo); } diff --git a/lightningd/chaintopology.h b/lightningd/chaintopology.h index 29b908623..802ef63ff 100644 --- a/lightningd/chaintopology.h +++ b/lightningd/chaintopology.h @@ -160,6 +160,8 @@ void setup_topology(struct chain_topology *topology, struct timers *timers, struct timerel poll_time, u32 first_peer_block); +void begin_topology(struct chain_topology *topo); + struct txlocator *locate_tx(const void *ctx, const struct chain_topology *topo, const struct bitcoin_txid *txid); void notify_new_block(struct lightningd *ld, unsigned int height); diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 335d9cde7..d678e8845 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -310,6 +310,12 @@ int main(int argc, char *argv[]) type_to_string(ltmp, struct pubkey, &ld->id), ld->alias, tal_hex(ltmp, ld->rgb), version()); + /* Start the peers. */ + activate_peers(ld); + + /* Now kick off topology update, now peers have watches. */ + begin_topology(ld->topology); + for (;;) { struct timer *expired; void *v = io_loop(&ld->timers, &expired); diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index c0677fd13..5da5fee2c 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -2714,6 +2714,38 @@ const char *peer_state_name(enum peer_state state) return "unknown"; } +static void activate_peer(struct peer *peer) +{ + assert(!peer->owner); + + switch (peer->state) { + case UNINITIALIZED: + abort(); + + case OPENINGD: + case CHANNELD_AWAITING_LOCKIN: + case CHANNELD_NORMAL: + case CHANNELD_SHUTTING_DOWN: + case CLOSINGD_SIGEXCHANGE: + case CLOSINGD_COMPLETE: + case FUNDING_SPEND_SEEN: + case ONCHAIND_CHEATED: + case ONCHAIND_THEIR_UNILATERAL: + case ONCHAIND_OUR_UNILATERAL: + case ONCHAIND_MUTUAL: + log_broken(peer->log, "FIXME: Implement activate_peer(%s)", + peer_state_name(peer->state)); + } +} + +void activate_peers(struct lightningd *ld) +{ + struct peer *p; + + list_for_each(&ld->peers, p, list) + activate_peer(p); +} + #if DEVELOPER static void json_sign_last_tx(struct command *cmd, const char *buffer, const jsmntok_t *params) diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index 663949cf2..548af4932 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -220,5 +220,8 @@ void peer_set_condition(struct peer *peer, enum peer_state oldstate, enum peer_state state); void setup_listeners(struct lightningd *ld); +/* We've loaded peers from database, set them going. */ +void activate_peers(struct lightningd *ld); + void free_htlcs(struct lightningd *ld, const struct peer *peer); #endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */ diff --git a/lightningd/test/run-find_my_path.c b/lightningd/test/run-find_my_path.c index 2bcb8e5c6..d1ead9a37 100644 --- a/lightningd/test/run-find_my_path.c +++ b/lightningd/test/run-find_my_path.c @@ -4,6 +4,12 @@ int unused_main(int argc, char *argv[]); #include "../lightningd.c" /* AUTOGENERATED MOCKS START */ +/* Generated stub for activate_peers */ +void activate_peers(struct lightningd *ld UNNEEDED) +{ fprintf(stderr, "activate_peers called!\n"); abort(); } +/* Generated stub for begin_topology */ +void begin_topology(struct chain_topology *topo UNNEEDED) +{ fprintf(stderr, "begin_topology called!\n"); abort(); } /* Generated stub for crashlog_activate */ void crashlog_activate(const char *argv0 UNNEEDED, struct log *log UNNEEDED) { fprintf(stderr, "crashlog_activate called!\n"); abort(); }