Skip to content

Commit

Permalink
common/gossip_store: avoid fd pass for new store, use end marker.
Browse files Browse the repository at this point in the history
This is also simpler.

Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Sep 25, 2020
1 parent 7731025 commit 0e1a891
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 139 deletions.
1 change: 1 addition & 0 deletions closingd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ CLOSINGD_COMMON_OBJS := \
common/version.o \
common/wire_error.o \
common/wireaddr.o \
gossipd/gossip_store_wiregen.o \
gossipd/gossipd_peerd_wiregen.o

ifeq ($(EXPERIMENTAL_FEATURES),1)
Expand Down
87 changes: 34 additions & 53 deletions common/gossip_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
#include <common/status.h>
#include <common/utils.h>
#include <errno.h>
#include <fcntl.h>
#include <gossipd/gossip_store_wiregen.h>
#include <inttypes.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <wire/peer_wire.h>

Expand Down Expand Up @@ -74,6 +78,32 @@ static void undo_read(int fd, int len, size_t wanted)
lseek(fd, -len, SEEK_CUR);
}

static void reopen_gossip_store(struct per_peer_state *pps,
const u8 *msg)
{
u64 equivalent_offset;
int newfd;

if (!fromwire_gossip_store_ended(msg, &equivalent_offset))
status_failed(STATUS_FAIL_GOSSIP_IO,
"Bad gossipd GOSSIP_STORE_ENDED msg: %s",
tal_hex(tmpctx, msg));

newfd = open(GOSSIP_STORE_FILENAME, O_RDONLY);
if (newfd < 0)
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Cannot open %s: %s",
GOSSIP_STORE_FILENAME,
strerror(errno));

status_debug("gossip_store at end, new fd moved to %"PRIu64,
equivalent_offset);
lseek(newfd, equivalent_offset, SEEK_SET);

close(pps->gossip_store_fd);
pps->gossip_store_fd = newfd;
}

u8 *gossip_store_next(const tal_t *ctx, struct per_peer_state *pps)
{
u8 *msg = NULL;
Expand Down Expand Up @@ -134,9 +164,11 @@ u8 *gossip_store_next(const tal_t *ctx, struct per_peer_state *pps)
continue;
}

/* Ignore gossipd internal messages. */
type = fromwire_peektype(msg);
if (type != WIRE_CHANNEL_ANNOUNCEMENT
if (type == WIRE_GOSSIP_STORE_ENDED)
reopen_gossip_store(pps, msg);
/* Ignore gossipd internal messages. */
else if (type != WIRE_CHANNEL_ANNOUNCEMENT
&& type != WIRE_CHANNEL_UPDATE
&& type != WIRE_NODE_ANNOUNCEMENT)
msg = tal_free(msg);
Expand All @@ -146,54 +178,3 @@ u8 *gossip_store_next(const tal_t *ctx, struct per_peer_state *pps)

return msg;
}

/* newfd is at offset 1. We need to adjust it to similar offset as our
* current one. */
void gossip_store_switch_fd(struct per_peer_state *pps,
int newfd, u64 offset_shorter)
{
u64 cur = lseek(pps->gossip_store_fd, 0, SEEK_CUR);

/* If we're already at end (common), we know where to go in new one. */
if (cur == lseek(pps->gossip_store_fd, 0, SEEK_END)) {
status_debug("gossip_store at end, new fd moved to %"PRIu64,
cur - offset_shorter);
assert(cur > offset_shorter);
lseek(newfd, cur - offset_shorter, SEEK_SET);
} else if (cur > offset_shorter) {
/* We're part way through. Worst case, we should move back by
* offset_shorter (that's how much the *end* moved), but in
* practice we'll probably end up retransmitting some stuff */
u64 target = cur - offset_shorter;
size_t num = 0;

status_debug("gossip_store new fd moving back %"PRIu64
" to %"PRIu64,
cur, target);
cur = 1;
while (cur < target) {
u32 msglen;
struct gossip_hdr hdr;

if (read(newfd, &hdr, sizeof(hdr)) != sizeof(hdr))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"gossip_store: "
"can't read hdr offset %"PRIu64
" in new store target %"PRIu64,
cur, target);
/* Skip over it. */
msglen = (be32_to_cpu(hdr.len)
& ~GOSSIP_STORE_LEN_DELETED_BIT);
cur = lseek(newfd, msglen, SEEK_CUR);
num++;
}
status_debug("gossip_store: skipped %zu records to %"PRIu64,
num, cur);
} else
status_debug("gossip_store new fd moving back %"PRIu64
" to start (offset_shorter=%"PRIu64")",
cur, offset_shorter);

close(pps->gossip_store_fd);
pps->gossip_store_fd = newfd;
}
14 changes: 2 additions & 12 deletions common/read_peer_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,9 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected,
void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES)
{
u8 *gossip;
u64 offset_shorter;

if (fromwire_gossipd_new_store_fd(msg, &offset_shorter)) {
gossip_store_switch_fd(pps, fdpass_recv(pps->gossip_fd),
offset_shorter);
goto out;
} else
/* It's a raw gossip msg: this copies or takes() */
gossip = tal_dup_talarr(tmpctx, u8, msg);
/* It's a raw gossip msg: this copies or takes() */
gossip = tal_dup_talarr(tmpctx, u8, msg);

/* Gossipd can send us gossip messages, OR errors */
if (fromwire_peektype(gossip) == WIRE_ERROR) {
Expand All @@ -125,10 +119,6 @@ void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES)
} else {
sync_crypto_write(pps, gossip);
}

out:
if (taken(msg))
tal_free(msg);
}

/* takes iff returns true */
Expand Down
7 changes: 2 additions & 5 deletions gossipd/gossip_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ bool gossip_store_compact(struct gossip_store *gs)
{
size_t count = 0, deleted = 0;
int fd;
u64 off, len = sizeof(gs->version), oldlen, idx;
u64 off, len = sizeof(gs->version), idx;
struct offmap *offmap;
struct gossip_hdr hdr;
struct offmap_iter oit;
Expand Down Expand Up @@ -578,18 +578,15 @@ bool gossip_store_compact(struct gossip_store *gs)
deleted, count, len);

/* Write end marker now new one is ready */
oldlen = gs->len;
append_msg(gs->fd, towire_gossip_store_ended(tmpctx, len),
0, false, &oldlen);
0, false, &gs->len);

gs->count = count;
gs->deleted = 0;
off = gs->len - len;
gs->len = len;
close(gs->fd);
gs->fd = fd;

update_peers_broadcast_index(gs->peers, off);
return true;

unlink_disable:
Expand Down
27 changes: 0 additions & 27 deletions gossipd/gossipd.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,32 +281,6 @@ static u8 *handle_channel_update_msg(struct peer *peer, const u8 *msg)
return NULL;
}

/*~ When we compact the gossip store, all the broadcast indexs move.
* We simply offset everyone, which means in theory they could retransmit
* some, but that's a lesser evil than skipping some. */
void update_peers_broadcast_index(struct list_head *peers, u32 offset)
{
struct peer *peer, *next;

list_for_each_safe(peers, peer, next, list) {
int gs_fd;
/*~ Since store has been compacted, they need a new fd for the
* new store. We also tell them how much this is shrunk, so
* they can (approximately) tell where to start in the new store.
*/
gs_fd = gossip_store_readonly_fd(peer->daemon->rstate->gs);
if (gs_fd < 0) {
status_broken("Can't get read-only gossip store fd:"
" killing peer");
tal_free(peer);
} else {
u8 *msg = towire_gossipd_new_store_fd(NULL, offset);
daemon_conn_send(peer->dc, take(msg));
daemon_conn_send_fd(peer->dc, gs_fd);
}
}
}

/*~ For simplicity, all pings and pongs are forwarded to us here in gossipd. */
static u8 *handle_ping(struct peer *peer, const u8 *ping)
{
Expand Down Expand Up @@ -522,7 +496,6 @@ static struct io_plan *peer_msg_in(struct io_conn *conn,

/* These are the ones we send, not them */
case WIRE_GOSSIPD_GET_UPDATE_REPLY:
case WIRE_GOSSIPD_NEW_STORE_FD:
break;
}

Expand Down
5 changes: 0 additions & 5 deletions gossipd/gossipd_peerd_wire.csv
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,6 @@ msgdata,gossipd_local_channel_update,fee_base_msat,u32,
msgdata,gossipd_local_channel_update,fee_proportional_millionths,u32,
msgdata,gossipd_local_channel_update,htlc_maximum_msat,amount_msat,

# Update your gossip_store fd: + gossip_store_fd
msgtype,gossipd_new_store_fd,3505
# How much shorter the new store is, so you can offset streaming.
msgdata,gossipd_new_store_fd,offset_shorter,u64,

# Send this channel_announcement
msgtype,gossipd_local_channel_announcement,3506
msgdata,gossipd_local_channel_announcement,len,u16,
Expand Down
28 changes: 1 addition & 27 deletions gossipd/gossipd_peerd_wiregen.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 1 addition & 8 deletions gossipd/gossipd_peerd_wiregen.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions openingd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ OPENINGD_COMMON_OBJS := \
common/version.o \
common/wire_error.o \
common/wireaddr.o \
gossipd/gossipd_peerd_wiregen.o \
lightningd/gossip_msg.o
gossipd/gossip_store_wiregen.o \
gossipd/gossipd_peerd_wiregen.o

ifeq ($(EXPERIMENTAL_FEATURES),1)
OPENINGD_COMMON_OBJS += common/psbt_open.o
Expand Down

0 comments on commit 0e1a891

Please sign in to comment.