mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
gossipd: allow reading from the store during load.
When we no longer keep channel_updates in memory, there's a path where we access them on load: when we promote a local channel to an announced channel. This breaks at the moment, since gs->fd == -1; change it to a writable flag instead. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
aeb72a05e3
commit
2135c7a024
1 changed files with 17 additions and 11 deletions
|
@ -19,7 +19,9 @@
|
||||||
#define GOSSIP_STORE_TEMP_FILENAME "gossip_store.tmp"
|
#define GOSSIP_STORE_TEMP_FILENAME "gossip_store.tmp"
|
||||||
|
|
||||||
struct gossip_store {
|
struct gossip_store {
|
||||||
/* This is -1 when we're loading */
|
/* This is false when we're loading */
|
||||||
|
bool writable;
|
||||||
|
|
||||||
int fd;
|
int fd;
|
||||||
u8 version;
|
u8 version;
|
||||||
|
|
||||||
|
@ -48,6 +50,7 @@ struct gossip_store *gossip_store_new(struct routing_state *rstate)
|
||||||
{
|
{
|
||||||
struct gossip_store *gs = tal(rstate, struct gossip_store);
|
struct gossip_store *gs = tal(rstate, struct gossip_store);
|
||||||
gs->count = 0;
|
gs->count = 0;
|
||||||
|
gs->writable = true;
|
||||||
gs->fd = open(GOSSIP_STORE_FILENAME, O_RDWR|O_APPEND|O_CREAT, 0600);
|
gs->fd = open(GOSSIP_STORE_FILENAME, O_RDWR|O_APPEND|O_CREAT, 0600);
|
||||||
gs->rstate = rstate;
|
gs->rstate = rstate;
|
||||||
gs->disable_compaction = false;
|
gs->disable_compaction = false;
|
||||||
|
@ -322,7 +325,7 @@ void gossip_store_maybe_compact(struct gossip_store *gs,
|
||||||
struct broadcast_state **bs)
|
struct broadcast_state **bs)
|
||||||
{
|
{
|
||||||
/* Don't compact while loading! */
|
/* Don't compact while loading! */
|
||||||
if (gs->fd == -1)
|
if (!gs->writable)
|
||||||
return;
|
return;
|
||||||
if (gs->count < 1000)
|
if (gs->count < 1000)
|
||||||
return;
|
return;
|
||||||
|
@ -337,7 +340,7 @@ u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg)
|
||||||
u64 off = gs->len;
|
u64 off = gs->len;
|
||||||
|
|
||||||
/* Should never get here during loading! */
|
/* Should never get here during loading! */
|
||||||
assert(gs->fd != -1);
|
assert(gs->writable);
|
||||||
|
|
||||||
if (!gossip_store_append(gs->fd, gs->rstate, gossip_msg, &gs->len)) {
|
if (!gossip_store_append(gs->fd, gs->rstate, gossip_msg, &gs->len)) {
|
||||||
status_broken("Failed writing to gossip store: %s",
|
status_broken("Failed writing to gossip store: %s",
|
||||||
|
@ -353,6 +356,10 @@ void gossip_store_add_channel_delete(struct gossip_store *gs,
|
||||||
const struct short_channel_id *scid)
|
const struct short_channel_id *scid)
|
||||||
{
|
{
|
||||||
u8 *msg = towire_gossip_store_channel_delete(NULL, scid);
|
u8 *msg = towire_gossip_store_channel_delete(NULL, scid);
|
||||||
|
|
||||||
|
/* Should never get here during loading! */
|
||||||
|
assert(gs->writable);
|
||||||
|
|
||||||
if (!gossip_store_append(gs->fd, gs->rstate, msg, &gs->len))
|
if (!gossip_store_append(gs->fd, gs->rstate, msg, &gs->len))
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
"Failed writing channel_delete to gossip store: %s",
|
"Failed writing channel_delete to gossip store: %s",
|
||||||
|
@ -426,21 +433,20 @@ void gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||||
struct short_channel_id scid;
|
struct short_channel_id scid;
|
||||||
const char *bad;
|
const char *bad;
|
||||||
size_t stats[] = {0, 0, 0, 0};
|
size_t stats[] = {0, 0, 0, 0};
|
||||||
int fd = gs->fd;
|
|
||||||
gs->fd = -1;
|
|
||||||
struct timeabs start = time_now();
|
struct timeabs start = time_now();
|
||||||
|
|
||||||
if (lseek(fd, gs->len, SEEK_SET) < 0) {
|
gs->writable = false;
|
||||||
|
if (lseek(gs->fd, gs->len, SEEK_SET) < 0) {
|
||||||
status_unusual("gossip_store: lseek failure");
|
status_unusual("gossip_store: lseek failure");
|
||||||
goto truncate_nomsg;
|
goto truncate_nomsg;
|
||||||
}
|
}
|
||||||
while (read(fd, &belen, sizeof(belen)) == sizeof(belen) &&
|
while (read(gs->fd, &belen, sizeof(belen)) == sizeof(belen) &&
|
||||||
read(fd, &becsum, sizeof(becsum)) == sizeof(becsum)) {
|
read(gs->fd, &becsum, sizeof(becsum)) == sizeof(becsum)) {
|
||||||
msglen = be32_to_cpu(belen);
|
msglen = be32_to_cpu(belen);
|
||||||
checksum = be32_to_cpu(becsum);
|
checksum = be32_to_cpu(becsum);
|
||||||
msg = tal_arr(tmpctx, u8, msglen);
|
msg = tal_arr(tmpctx, u8, msglen);
|
||||||
|
|
||||||
if (read(fd, msg, msglen) != msglen) {
|
if (read(gs->fd, msg, msglen) != msglen) {
|
||||||
status_unusual("gossip_store: truncated file?");
|
status_unusual("gossip_store: truncated file?");
|
||||||
goto truncate_nomsg;
|
goto truncate_nomsg;
|
||||||
}
|
}
|
||||||
|
@ -508,7 +514,7 @@ truncate_nomsg:
|
||||||
* miss channel_delete msgs. If we put block numbers into the store
|
* miss channel_delete msgs. If we put block numbers into the store
|
||||||
* as we process them, we can know how far we need to roll back if we
|
* as we process them, we can know how far we need to roll back if we
|
||||||
* truncate the store */
|
* truncate the store */
|
||||||
if (ftruncate(fd, 1) != 0)
|
if (ftruncate(gs->fd, 1) != 0)
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
"Truncating store: %s", strerror(errno));
|
"Truncating store: %s", strerror(errno));
|
||||||
out:
|
out:
|
||||||
|
@ -524,5 +530,5 @@ out:
|
||||||
status_trace("gossip_store: Read %zu/%zu/%zu/%zu cannounce/cupdate/nannounce/cdelete from store in %"PRIu64" bytes",
|
status_trace("gossip_store: Read %zu/%zu/%zu/%zu cannounce/cupdate/nannounce/cdelete from store in %"PRIu64" bytes",
|
||||||
stats[0], stats[1], stats[2], stats[3],
|
stats[0], stats[1], stats[2], stats[3],
|
||||||
gs->len);
|
gs->len);
|
||||||
gs->fd = fd;
|
gs->writable = true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue