diff --git a/common/gossip_store.c b/common/gossip_store.c index 13e0ce01d..324c3f7be 100644 --- a/common/gossip_store.c +++ b/common/gossip_store.c @@ -84,6 +84,7 @@ u8 *gossip_store_next(const tal_t *ctx, struct per_peer_state *pps) while (!msg) { struct gossip_hdr hdr; u32 msglen, checksum, timestamp; + bool push; int type, r; r = read(pps->gossip_store_fd, &hdr, sizeof(hdr)); @@ -99,12 +100,15 @@ u8 *gossip_store_next(const tal_t *ctx, struct per_peer_state *pps) if (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) { /* Skip over it. */ lseek(pps->gossip_store_fd, - be32_to_cpu(hdr.len) & ~GOSSIP_STORE_LEN_DELETED_BIT, + be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK, SEEK_CUR); continue; } msglen = be32_to_cpu(hdr.len); + push = (msglen & GOSSIP_STORE_LEN_PUSH_BIT); + msglen &= GOSSIP_STORE_LEN_MASK; + checksum = be32_to_cpu(hdr.crc); timestamp = be32_to_cpu(hdr.timestamp); msg = tal_arr(ctx, u8, msglen); @@ -135,7 +139,7 @@ u8 *gossip_store_next(const tal_t *ctx, struct per_peer_state *pps) && type != WIRE_CHANNEL_UPDATE && type != WIRE_NODE_ANNOUNCEMENT) msg = tal_free(msg); - else if (!timestamp_filter(pps, timestamp)) + else if (!push && !timestamp_filter(pps, timestamp)) msg = tal_free(msg); } diff --git a/common/gossip_store.h b/common/gossip_store.h index 457f56774..4b351cd6c 100644 --- a/common/gossip_store.h +++ b/common/gossip_store.h @@ -17,6 +17,15 @@ struct per_peer_state; */ #define GOSSIP_STORE_LEN_DELETED_BIT 0x80000000U +/** + * Bit of length we use to mark an important record. + */ +#define GOSSIP_STORE_LEN_PUSH_BIT 0x40000000U + +/* Mask for extracting just the length part of len field */ +#define GOSSIP_STORE_LEN_MASK \ + (~(GOSSIP_STORE_LEN_PUSH_BIT | GOSSIP_STORE_LEN_DELETED_BIT)) + /** * gossip_hdr -- On-disk format header. */ diff --git a/devtools/dump-gossipstore.c b/devtools/dump-gossipstore.c index b60f04f51..97ca545d3 100644 --- a/devtools/dump-gossipstore.c +++ b/devtools/dump-gossipstore.c @@ -55,11 +55,12 @@ int main(int argc, char *argv[]) struct amount_sat sat; u32 msglen = be32_to_cpu(hdr.len); u8 *msg, *inner; - bool deleted; + bool deleted, push; deleted = (msglen & GOSSIP_STORE_LEN_DELETED_BIT); + push = (msglen & GOSSIP_STORE_LEN_PUSH_BIT); - msglen &= ~GOSSIP_STORE_LEN_DELETED_BIT; + msglen &= GOSSIP_STORE_LEN_MASK; msg = tal_arr(NULL, u8, msglen); if (read(fd, msg, msglen) != msglen) errx(1, "%zu: Truncated file?", off); @@ -68,7 +69,9 @@ int main(int argc, char *argv[]) != crc32c(be32_to_cpu(hdr.timestamp), msg, msglen)) warnx("Checksum verification failed"); - printf("%zu: %s", off, deleted ? "DELETED " : ""); + printf("%zu: %s%s", off, + deleted ? "DELETED " : "", + push ? "PUSH " : ""); if (deleted && !print_deleted) { printf("\n"); goto end; diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 5b8726881..d0e6e1d28 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -157,7 +157,7 @@ static u32 gossip_store_compact_offline(void) size_t msglen; u8 *msg; - msglen = (be32_to_cpu(hdr.len) & ~GOSSIP_STORE_LEN_DELETED_BIT); + msglen = (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK); msg = tal_arr(NULL, u8, msglen); if (!read_all(old_fd, msg, msglen)) { status_broken("gossip_store_compact_offline: reading msg len %zu from store: %s", @@ -272,6 +272,9 @@ static size_t transfer_store_msg(int from_fd, size_t from_off, return 0; } + /* Ignore any non-length bits (e.g. push) */ + msglen &= GOSSIP_STORE_LEN_MASK; + /* FIXME: Reuse buffer? */ msg = tal_arr(tmpctx, u8, sizeof(hdr) + msglen); memcpy(msg, &hdr, sizeof(hdr)); @@ -395,7 +398,7 @@ bool gossip_store_compact(struct gossip_store *gs) u32 msglen, wlen; int msgtype; - msglen = (be32_to_cpu(hdr.len) & ~GOSSIP_STORE_LEN_DELETED_BIT); + msglen = (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK); if (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) { off += sizeof(hdr) + msglen; deleted++; @@ -547,7 +550,7 @@ static u32 delete_by_index(struct gossip_store *gs, u32 index, int type) gs->deleted++; return index + sizeof(struct gossip_hdr) - + (be32_to_cpu(belen) & ~GOSSIP_STORE_LEN_DELETED_BIT); + + (be32_to_cpu(belen) & GOSSIP_STORE_LEN_MASK); } void gossip_store_delete(struct gossip_store *gs, @@ -595,7 +598,7 @@ const u8 *gossip_store_get(const tal_t *ctx, "/%"PRIu64"", offset, gs->len); - msglen = be32_to_cpu(hdr.len); + msglen = (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK); checksum = be32_to_cpu(hdr.crc); msg = tal_arr(ctx, u8, msglen); if (pread(gs->fd, msg, msglen, offset + sizeof(hdr)) != msglen) @@ -651,7 +654,7 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs) gs->writable = false; while (pread(gs->fd, &hdr, sizeof(hdr), gs->len) == sizeof(hdr)) { - msglen = be32_to_cpu(hdr.len) & ~GOSSIP_STORE_LEN_DELETED_BIT; + msglen = be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK; checksum = be32_to_cpu(hdr.crc); msg = tal_arr(tmpctx, u8, msglen);