diff --git a/plugins/recover.c b/plugins/recover.c index 4af59f0c2857..565401754465 100644 --- a/plugins/recover.c +++ b/plugins/recover.c @@ -11,10 +11,14 @@ #include static struct plugin *plugin; -static struct plugin_timer *lost_state_timer; +static struct gossmap *global_gossmap; +static struct plugin_timer *lost_state_timer, *find_exes_timer, *peer_storage_timer; + /* This tells if we are already in the process of recovery. */ static bool recovery, already_has_peers; static void do_check_lost_peer (void *unused); +static void do_check_gossip (void *unused); +static void do_find_peer_storage (void *unused); static struct node_id local_id; /* List of most connected nodes on the network */ @@ -60,6 +64,85 @@ static struct command_result *after_emergency_recover(struct command *cmd, return command_still_pending(cmd); } +static struct command_result *after_restorefrompeer(struct command *cmd, + const char *buf, + const jsmntok_t *params, + void *cb_arg UNUSED) +{ + plugin_log(plugin, LOG_DBG, "restorefrompeer called"); + + peer_storage_timer = plugin_timer(plugin, time_from_sec(5), do_find_peer_storage, NULL); + return command_still_pending(NULL); +} + +static struct command_result *find_peer_storage (void *unused) { + peer_storage_timer = NULL; + + struct out_req *req; + req = jsonrpc_request_start(plugin, NULL, "restorefrompeer", + after_restorefrompeer, + &forward_error, NULL); + + return send_outreq(plugin, req); +} + +static void do_find_peer_storage (void *unused) { + find_peer_storage(NULL); + return; +} + + +static void do_check_gossip (void *unused) { + find_exes_timer = NULL; + + gossmap_refresh(global_gossmap, NULL); + + plugin_log(plugin, LOG_DBG, "Finding our node in gossip"); + + struct gossmap_node *n = gossmap_find_node(global_gossmap, &local_id); + + if (n) { + for (struct gossmap_chan *c = gossmap_first_chan(global_gossmap); + c; + c = gossmap_next_chan(global_gossmap, c)) { + struct gossmap_node *x = gossmap_node_byidx(global_gossmap, c->half[1].nodeidx); + struct gossmap_node *y = gossmap_node_byidx(global_gossmap, c->half[0].nodeidx); + struct node_id a, b; + gossmap_node_get_id(global_gossmap, x, &a); + gossmap_node_get_id(global_gossmap, y, &b); + + struct out_req *req; + bool isPeerA = false; + + req = jsonrpc_request_start(plugin, + NULL, + "connect", + &forward_result, + &forward_error, + NULL); + + if (!node_id_cmp(&b, &local_id)) + isPeerA = true; + + if (isPeerA) + json_add_node_id(req->js, "id", &a); + else + json_add_node_id(req->js, "id", &b); + + plugin_log(plugin, LOG_DBG, "Connecting to: %s", isPeerA?type_to_string(tmpctx, struct node_id, &a): + type_to_string(tmpctx, struct node_id, &b)); + + send_outreq(plugin, req); + + } + + peer_storage_timer = plugin_timer(plugin, time_from_sec(5), do_find_peer_storage, NULL); + return; + } + + find_exes_timer = plugin_timer(plugin, time_from_sec(5), do_check_gossip, NULL); + return; +} static void entering_recovery_mode(void *unused) { if(!already_has_peers) { @@ -87,6 +170,7 @@ static void entering_recovery_mode(void *unused) { NULL); send_outreq(plugin, req_emer_recovery); + find_exes_timer = plugin_timer(plugin, time_from_sec(5), do_check_gossip, NULL); return; } @@ -150,6 +234,7 @@ static const char *init(struct plugin *p, recovery = false; lost_state_timer = plugin_timer(plugin, time_from_sec(2), do_check_lost_peer, NULL); u32 num_peers; + size_t num_cupdates_rejected; /* Find number of peers */ rpc_scan(p, "getinfo", @@ -158,6 +243,21 @@ static const char *init(struct plugin *p, JSON_SCAN(json_to_node_id, &local_id), JSON_SCAN(json_to_u32, &num_peers)); + global_gossmap = gossmap_load(NULL, + GOSSIP_STORE_FILENAME, + &num_cupdates_rejected); + + if (!global_gossmap) + plugin_err(p, "Could not load gossmap %s: %s", + GOSSIP_STORE_FILENAME, strerror(errno)); + + if (num_cupdates_rejected) + plugin_log(p, LOG_DBG, + "gossmap ignored %zu channel updates", + num_cupdates_rejected); + + plugin_log(p, LOG_DBG, "Gossmap loaded!"); + already_has_peers = num_peers > 2 ? 1: 0; return NULL;