diff --git a/plugins/chanbackup.c b/plugins/chanbackup.c index f392117b51ff..dbdc14318ca9 100644 --- a/plugins/chanbackup.c +++ b/plugins/chanbackup.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -388,6 +389,92 @@ static struct command_result *after_send_scb(struct command *cmd, return send_outreq(cmd->plugin, req); } +struct info { + size_t idx; +}; + +static struct command_result *after_send_scb_single(struct command *cmd, + const char *buf, + const jsmntok_t *params, + struct info *info) +{ + plugin_log(cmd->plugin, LOG_INFORM, "Peer storage sent to"); + if (--info->idx != 0) + return command_still_pending(cmd); + + return notification_handled(cmd); +} + +static struct command_result *after_listpeers(struct command *cmd, + const char *buf, + const jsmntok_t *params, + void *cb_arg UNUSED) +{ + const jsmntok_t *peers, *peer, *nodeid; + struct out_req *req; + struct stat st; + size_t i; + struct info *info = tal(cmd, struct info); + struct node_id *node_id = tal(cmd, struct node_id); + bool is_connected; + + int fd = open("emergency.recover", O_RDONLY); + if (fd < 0) + plugin_err(cmd->plugin, "Opening: %s", strerror(errno)); + + if (stat("emergency.recover", &st) != 0) + plugin_err(cmd->plugin, "SCB file is corrupted!: %s", + strerror(errno)); + + u8 *scb = tal_arr(cmd, u8, st.st_size); + + if (!read_all(fd, scb, tal_bytelen(scb))) { + plugin_log(cmd->plugin, LOG_DBG, "SCB file is corrupted!: %s", + strerror(errno)); + return NULL; + } + + u8 *serialise_scb = towire_peer_storage(cmd, scb); + + if (fsync(fd) != 0) { + plugin_err(cmd->plugin, "closing: %s", strerror(errno)); + } + + if (close(fd) != 0) { + plugin_err(cmd->plugin, "closing: %s", strerror(errno)); + } + + peers = json_get_member(buf, params, "peers"); + + info->idx = 0; + json_for_each_arr(i, peer, peers) { + json_to_bool(buf, json_get_member(buf, peer, "connected"), + &is_connected); + + if (is_connected) { + nodeid = json_get_member(buf, peer, "id"); + json_to_node_id(buf, nodeid, node_id); + + req = jsonrpc_request_start(cmd->plugin, + cmd, + "sendcustommsg", + after_send_scb_single, + &forward_error, + info); + + json_add_node_id(req->js, "node_id", node_id); + json_add_hex(req->js, "msg", serialise_scb, + tal_bytelen(serialise_scb)); + info->idx++; + send_outreq(cmd->plugin, req); + } + } + + if (info->idx == 0) + return notification_handled(cmd); + return command_still_pending(cmd); +} + static struct command_result *after_staticbackup(struct command *cmd, const char *buf, const jsmntok_t *params, @@ -395,11 +482,21 @@ static struct command_result *after_staticbackup(struct command *cmd, { struct scb_chan **scb_chan; const jsmntok_t *scbs = json_get_member(buf, params, "scb"); + struct out_req *req; json_to_scb_chan(buf, scbs, &scb_chan); plugin_log(cmd->plugin, LOG_INFORM, "Updating the SCB"); update_scb(cmd->plugin, scb_chan); - return notification_handled(cmd); + plugin_log(cmd->plugin, LOG_INFORM, "Updating the SCB2"); + struct info *info = tal(cmd, struct info); + info->idx = 0; + req = jsonrpc_request_start(cmd->plugin, + cmd, + "listpeers", + after_listpeers, + &forward_error, + info); + return send_outreq(cmd->plugin, req); } static struct command_result *json_state_changed(struct command *cmd, @@ -740,7 +837,7 @@ int main(int argc, char *argv[]) set_feature_bit(&features->bits[INIT_FEATURE], YOUR_PEER_STORAGE_FEATUREBIT); - plugin_main(argv, init, PLUGIN_RESTARTABLE, true, NULL, + plugin_main(argv, init, PLUGIN_STATIC, true, features, commands, ARRAY_SIZE(commands), notifs, ARRAY_SIZE(notifs), hooks, ARRAY_SIZE(hooks), NULL, 0, /* Notification topics we publish */