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 <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-01-03 15:56:44 +10:30 committed by Christian Decker
parent 7b735e5de8
commit 1b41335121
6 changed files with 58 additions and 9 deletions

View File

@ -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);
}

View File

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

View File

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

View File

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

View File

@ -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 */

View File

@ -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(); }