diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index b791a0828..e48fe673d 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -156,8 +156,7 @@ static bool gossip_store_append(int fd, struct routing_state *rstate, const u8 * * Creates a new file, writes all the updates from the `broadcast_state`, and * then atomically swaps the files. */ - -static void gossip_store_compact(struct gossip_store *gs) +bool gossip_store_compact(struct gossip_store *gs) { size_t count = 0; u64 index = 0; @@ -206,7 +205,7 @@ static void gossip_store_compact(struct gossip_store *gs) gs->count = count; close(gs->fd); gs->fd = fd; - return; + return true; unlink_disable: unlink(GOSSIP_STORE_TEMP_FILENAME); @@ -214,6 +213,7 @@ disable: status_trace("Encountered an error while compacting, disabling " "future compactions."); gs->disable_compaction = true; + return false; } void gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg) diff --git a/gossipd/gossip_store.h b/gossipd/gossip_store.h index 03406fcf6..a25004458 100644 --- a/gossipd/gossip_store.h +++ b/gossipd/gossip_store.h @@ -39,4 +39,6 @@ void gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg); void gossip_store_add_channel_delete(struct gossip_store *gs, const struct short_channel_id *scid); +/* Expose for dev-compact-gossip-store */ +bool gossip_store_compact(struct gossip_store *gs); #endif /* LIGHTNING_GOSSIPD_GOSSIP_STORE_H */ diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index 288f9dcb3..8c6ffb470 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -142,6 +142,13 @@ gossip_dev_memleak,3033 gossip_dev_memleak_reply,3133 gossip_dev_memleak_reply,,leak,bool +# master -> gossipd: please rewrite the gossip_store +gossip_dev_compact_store,3034 + +# gossipd -> master: ok +gossip_dev_compact_store_reply,3134 +gossip_dev_compact_store_reply,,success,bool + #include # master -> gossipd: get route_info for our incoming channels diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index e2e3020eb..6213eda7f 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -2490,6 +2490,17 @@ static struct io_plan *dev_gossip_memleak(struct io_conn *conn, found_leak))); return daemon_conn_read_next(conn, daemon->master); } + +static struct io_plan *dev_compact_store(struct io_conn *conn, + struct daemon *daemon, + const u8 *msg) +{ + bool done = gossip_store_compact(daemon->rstate->store); + daemon_conn_send(daemon->master, + take(towire_gossip_dev_compact_store_reply(NULL, + done))); + return daemon_conn_read_next(conn, daemon->master); +} #endif /* DEVELOPER */ /*~ lightningd: so, tell me about this channel, so we can forward to it. */ @@ -2749,6 +2760,8 @@ static struct io_plan *recv_req(struct io_conn *conn, return dev_gossip_suppress(conn, daemon, msg); case WIRE_GOSSIP_DEV_MEMLEAK: return dev_gossip_memleak(conn, daemon, msg); + case WIRE_GOSSIP_DEV_COMPACT_STORE: + return dev_compact_store(conn, daemon, msg); #else case WIRE_GOSSIP_QUERY_SCIDS: case WIRE_GOSSIP_SEND_TIMESTAMP_FILTER: @@ -2756,6 +2769,7 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_GOSSIP_DEV_SET_MAX_SCIDS_ENCODE_SIZE: case WIRE_GOSSIP_DEV_SUPPRESS: case WIRE_GOSSIP_DEV_MEMLEAK: + case WIRE_GOSSIP_DEV_COMPACT_STORE: break; #endif /* !DEVELOPER */ @@ -2770,6 +2784,7 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY: case WIRE_GOSSIP_GET_TXOUT: case WIRE_GOSSIP_DEV_MEMLEAK_REPLY: + case WIRE_GOSSIP_DEV_COMPACT_STORE_REPLY: break; } diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 9a881ba43..e316d6a34 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -121,6 +121,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIP_DEV_SUPPRESS: case WIRE_GOSSIP_LOCAL_CHANNEL_CLOSE: case WIRE_GOSSIP_DEV_MEMLEAK: + case WIRE_GOSSIP_DEV_COMPACT_STORE: /* This is a reply, so never gets through to here. */ case WIRE_GOSSIP_GETNODES_REPLY: case WIRE_GOSSIP_GETROUTE_REPLY: @@ -130,6 +131,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIP_GET_CHANNEL_PEER_REPLY: case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY: case WIRE_GOSSIP_DEV_MEMLEAK_REPLY: + case WIRE_GOSSIP_DEV_COMPACT_STORE_REPLY: break; case WIRE_GOSSIP_PING_REPLY: @@ -680,4 +682,46 @@ static const struct json_command dev_suppress_gossip = { "Stop this node from sending any more gossip." }; AUTODATA(json_command, &dev_suppress_gossip); + +static void dev_compact_gossip_store_reply(struct subd *gossip UNUSED, + const u8 *reply, + const int *fds UNUSED, + struct command *cmd) +{ + bool success; + + if (!fromwire_gossip_dev_compact_store_reply(reply, &success)) { + was_pending(command_fail(cmd, LIGHTNINGD, + "Gossip gave bad dev_gossip_compact_store_reply")); + return; + } + + if (!success) + was_pending(command_fail(cmd, LIGHTNINGD, + "gossip_compact_store failed")); + else + was_pending(command_success(cmd, null_response(cmd))); +} + +static struct command_result *json_dev_compact_gossip_store(struct command *cmd, + const char *buffer, + const jsmntok_t *obj UNNEEDED, + const jsmntok_t *params) +{ + u8 *msg; + if (!param(cmd, buffer, params, NULL)) + return command_param_failed(); + + msg = towire_gossip_dev_compact_store(NULL); + subd_req(cmd->ld->gossip, cmd->ld->gossip, + take(msg), -1, 0, dev_compact_gossip_store_reply, cmd); + return command_still_pending(cmd); +} + +static const struct json_command dev_compact_gossip_store = { + "dev-compact-gossip-store", + json_dev_compact_gossip_store, + "Ask gossipd to rewrite the gossip store." +}; +AUTODATA(json_command, &dev_compact_gossip_store); #endif /* DEVELOPER */