From 317a830e9405eb6d53cea336fc7626efe21beb20 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 30 Aug 2018 09:34:28 +0930 Subject: [PATCH] devtools: dump-gossipstore. Not very useful by itself, but when combined with decodemsg it can tell us quite a bit. Signed-off-by: Rusty Russell --- devtools/.gitignore | 1 + devtools/Makefile | 9 ++-- devtools/dump-gossipstore.c | 82 +++++++++++++++++++++++++++++++++++++ gossipd/gossip_store.c | 11 +++-- gossipd/gossip_store.h | 2 + 5 files changed, 96 insertions(+), 9 deletions(-) create mode 100644 devtools/dump-gossipstore.c diff --git a/devtools/.gitignore b/devtools/.gitignore index f37d42aab..eb53afe43 100644 --- a/devtools/.gitignore +++ b/devtools/.gitignore @@ -1,3 +1,4 @@ bolt11-cli decodemsg onion +dump-gossipstore diff --git a/devtools/Makefile b/devtools/Makefile index 1b8625fce..c2af6a2a7 100644 --- a/devtools/Makefile +++ b/devtools/Makefile @@ -1,6 +1,6 @@ DEVTOOLS_SRC := devtools/gen_print_wire.c devtools/gen_print_onion_wire.c devtools/print_wire.c DEVTOOLS_OBJS := $(DEVTOOLS_SRC:.c=.o) -DEVTOOLS_TOOL_SRC := devtools/bolt11-cli.c devtools/decodemsg.c devtools/onion.c +DEVTOOLS_TOOL_SRC := devtools/bolt11-cli.c devtools/decodemsg.c devtools/onion.c devtools/dump-gossipstore.c DEVTOOLS_TOOL_OBJS := $(DEVTOOLS_TOOL_SRC:.c=.o) DEVTOOLS_COMMON_OBJS := \ @@ -15,7 +15,7 @@ DEVTOOLS_COMMON_OBJS := \ common/version.o \ common/wireaddr.o -devtools-all: devtools/bolt11-cli devtools/decodemsg devtools/onion +devtools-all: devtools/bolt11-cli devtools/decodemsg devtools/onion devtools/dump-gossipstore devtools/gen_print_wire.h: $(WIRE_GEN) wire/gen_peer_wire_csv $(WIRE_GEN) --bolt --printwire --header $@ wire_type < wire/gen_peer_wire_csv > $@ @@ -33,6 +33,9 @@ devtools/bolt11-cli: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCA devtools/decodemsg: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/decodemsg.o +devtools/dump-gossipstore: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/dump-gossipstore.o gossipd/gen_gossip_store.o + +devtools/dump-gossipstore.o: gossipd/gen_gossip_store.h devtools/onion.c: ccan/config.h devtools/onion: $(DEVTOOLS_OBJS) $(DEVTOOLS_COMMON_OBJS) $(JSMN_OBJS) $(CCAN_OBJS) $(BITCOIN_OBJS) wire/fromwire.o wire/towire.o devtools/onion.o common/sphinx.o @@ -42,7 +45,7 @@ devtools/gen_print_wire.o: devtools/gen_print_wire.h wire/gen_peer_wire.h devtoo devtools/gen_print_onion_wire.o: devtools/gen_print_onion_wire.h devtools/print_wire.h # Make sure these depend on everything. -ALL_PROGRAMS += devtools/bolt11-cli devtools/decodemsg devtools/onion +ALL_PROGRAMS += devtools/bolt11-cli devtools/decodemsg devtools/onion devtools/dump-gossipstore ALL_OBJS += $(DEVTOOLS_OBJS) $(DEVTOOLS_TOOL_OBJS) check-source: $(DEVTOOLS_SRC:%=check-src-include-order/%) $(DEVTOOLS_TOOLS_SRC:%=check-src-include-order/%) diff --git a/devtools/dump-gossipstore.c b/devtools/dump-gossipstore.c new file mode 100644 index 000000000..7604ce17f --- /dev/null +++ b/devtools/dump-gossipstore.c @@ -0,0 +1,82 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + int fd; + u8 version; + beint32_t belen, becsum; + + setup_locale(); + + if (argc > 2) + errx(1, "Need the filename of a gossip store, or stdin"); + + if (argc == 2) { + fd = open(argv[1], O_RDONLY); + if (fd < 0) + err(1, "Opening %s", argv[1]); + } else + fd = STDIN_FILENO; + + if (read(fd, &version, sizeof(version)) != sizeof(version)) + errx(1, "Empty file"); + + if (version != GOSSIP_STORE_VERSION) + warnx("UNSUPPORTED GOSSIP VERSION %u (expected %u)", + version, GOSSIP_STORE_VERSION); + + printf("GOSSIP VERSION %u\n", version); + + while (read(fd, &belen, sizeof(belen)) == sizeof(belen) && + read(fd, &becsum, sizeof(becsum)) == sizeof(becsum)) { + u64 satoshis; + struct short_channel_id scid; + u8 *gossip_msg; + u32 msglen = be32_to_cpu(belen); + u8 *msg = tal_arr(NULL, u8, msglen); + + if (read(fd, msg, msglen) != msglen) + errx(1, "Truncated file?"); + + if (be32_to_cpu(becsum) != crc32c(0, msg, msglen)) + warnx("Checksum verification failed"); + + if (fromwire_gossip_store_channel_announcement(msg, msg, + &gossip_msg, + &satoshis)) { + printf("channel_announce for %"PRIu64" satoshis: %s\n", + satoshis, tal_hex(msg, gossip_msg)); + } else if (fromwire_gossip_store_channel_update(msg, msg, + &gossip_msg)) { + printf("channel_update: %s\n", + tal_hex(msg, gossip_msg)); + } else if (fromwire_gossip_store_node_announcement(msg, msg, + &gossip_msg)) { + printf("node_announcement: %s\n", + tal_hex(msg, gossip_msg)); + } else if (fromwire_gossip_store_channel_delete(msg, &scid)) { + printf("channel_delete: %s\n", + type_to_string(msg, struct short_channel_id, + &scid)); + } else if (fromwire_gossip_store_local_add_channel( + msg, msg, &gossip_msg)) { + printf("local_add_channel: %s\n", + tal_hex(msg, gossip_msg)); + } else { + warnx("Unknown message %u", fromwire_peektype(msg)); + } + tal_free(msg); + } + return 0; +} diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 8060b7d77..2e070e69f 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -16,7 +16,6 @@ #define GOSSIP_STORE_FILENAME "gossip_store" #define GOSSIP_STORE_TEMP_FILENAME "gossip_store.tmp" -static u8 gossip_store_version = 0x02; struct gossip_store { int fd; @@ -62,17 +61,17 @@ struct gossip_store *gossip_store_new(const tal_t *ctx, if (read(gs->fd, &gs->version, sizeof(gs->version)) == sizeof(gs->version)) { /* Version match? All good */ - if (gs->version == gossip_store_version) + if (gs->version == GOSSIP_STORE_VERSION) return gs; status_unusual("Gossip store version %u not %u: removing", - gs->version, gossip_store_version); + gs->version, GOSSIP_STORE_VERSION); if (ftruncate(gs->fd, 0) != 0) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Truncating store: %s", strerror(errno)); } /* Empty file, write version byte */ - gs->version = gossip_store_version; + gs->version = GOSSIP_STORE_VERSION; if (write(gs->fd, &gs->version, sizeof(gs->version)) != sizeof(gs->version)) status_failed(STATUS_FAIL_INTERNAL_ERROR, @@ -177,8 +176,8 @@ static void gossip_store_compact(struct gossip_store *gs) goto disable; } - if (write(fd, &gossip_store_version, sizeof(gossip_store_version)) - != sizeof(gossip_store_version)) { + if (write(fd, &gs->version, sizeof(gs->version)) + != sizeof(gs->version)) { status_broken("Writing version to store: %s", strerror(errno)); goto unlink_disable; } diff --git a/gossipd/gossip_store.h b/gossipd/gossip_store.h index e4f786352..6a78d2ca9 100644 --- a/gossipd/gossip_store.h +++ b/gossipd/gossip_store.h @@ -11,6 +11,8 @@ /** * gossip_store -- On-disk storage related information */ +#define GOSSIP_STORE_VERSION 2 + struct gossip_store; struct routing_state;