mirror of
https://github.com/ElementsProject/lightning.git
synced 2024-11-19 18:11:28 +01:00
common/gossip_store: clean up header.
It's actually two separate u16 fields, so actually treat it as such! Cleans up zombie handling code a bit too. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
83c690fe5f
commit
0274d88bad
@ -118,7 +118,8 @@ u8 *gossip_store_next(const tal_t *ctx,
|
||||
|
||||
while (!msg) {
|
||||
struct gossip_hdr hdr;
|
||||
u32 msglen, checksum, timestamp;
|
||||
u16 msglen, flags;
|
||||
u32 checksum, timestamp;
|
||||
bool push, ratelimited;
|
||||
int type, r;
|
||||
|
||||
@ -126,13 +127,13 @@ u8 *gossip_store_next(const tal_t *ctx,
|
||||
if (r != sizeof(hdr))
|
||||
return NULL;
|
||||
|
||||
msglen = be32_to_cpu(hdr.len);
|
||||
push = (msglen & GOSSIP_STORE_LEN_PUSH_BIT);
|
||||
ratelimited = (msglen & GOSSIP_STORE_LEN_RATELIMIT_BIT);
|
||||
msglen &= GOSSIP_STORE_LEN_MASK;
|
||||
msglen = be16_to_cpu(hdr.len);
|
||||
flags = be16_to_cpu(hdr.flags);
|
||||
push = (flags & GOSSIP_STORE_PUSH_BIT);
|
||||
ratelimited = (flags & GOSSIP_STORE_RATELIMIT_BIT);
|
||||
|
||||
/* Skip any deleted entries. */
|
||||
if (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) {
|
||||
if (flags & GOSSIP_STORE_DELETED_BIT) {
|
||||
*off += r + msglen;
|
||||
continue;
|
||||
}
|
||||
@ -146,14 +147,6 @@ u8 *gossip_store_next(const tal_t *ctx,
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Messages can be up to 64k, but we also have internal ones:
|
||||
* 128k is plenty. */
|
||||
if (msglen > 128 * 1024)
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"gossip_store: oversize msg len %u at"
|
||||
" offset %zu (was at %zu)",
|
||||
msglen, *off, initial_off);
|
||||
|
||||
checksum = be32_to_cpu(hdr.crc);
|
||||
msg = tal_arr(ctx, u8, msglen);
|
||||
r = pread(*gossip_store_fd, msg, msglen, *off + r);
|
||||
@ -201,7 +194,7 @@ size_t find_gossip_store_end(int gossip_store_fd, size_t off)
|
||||
while ((r = pread(gossip_store_fd, &buf,
|
||||
sizeof(buf.hdr) + sizeof(buf.type), off))
|
||||
== sizeof(buf.hdr) + sizeof(buf.type)) {
|
||||
u32 msglen = be32_to_cpu(buf.hdr.len) & GOSSIP_STORE_LEN_MASK;
|
||||
u16 msglen = be16_to_cpu(buf.hdr.len);
|
||||
|
||||
/* Don't swallow end marker! */
|
||||
if (buf.type == CPU_TO_BE16(WIRE_GOSSIP_STORE_ENDED))
|
||||
@ -227,7 +220,8 @@ size_t find_gossip_store_by_timestamp(int gossip_store_fd,
|
||||
while ((r = pread(gossip_store_fd, &buf,
|
||||
sizeof(buf.hdr) + sizeof(buf.type), off))
|
||||
== sizeof(buf.hdr) + sizeof(buf.type)) {
|
||||
u32 msglen = be32_to_cpu(buf.hdr.len) & GOSSIP_STORE_LEN_MASK;
|
||||
u16 msglen = be16_to_cpu(buf.hdr.len);
|
||||
u16 flags = be16_to_cpu(buf.hdr.flags);
|
||||
u16 type = be16_to_cpu(buf.type);
|
||||
|
||||
/* Don't swallow end marker! Reset, as they will call
|
||||
@ -236,7 +230,7 @@ size_t find_gossip_store_by_timestamp(int gossip_store_fd,
|
||||
return 1;
|
||||
|
||||
/* Only to-be-broadcast types have valid timestamps! */
|
||||
if (!(be32_to_cpu(buf.hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT)
|
||||
if (!(flags & GOSSIP_STORE_DELETED_BIT)
|
||||
&& public_msg_type(type)
|
||||
&& be32_to_cpu(buf.hdr.timestamp) >= timestamp) {
|
||||
break;
|
||||
|
@ -25,39 +25,32 @@ struct gossip_rcvd_filter;
|
||||
#define GOSSIP_STORE_MINOR_VERSION(verbyte) ((verbyte) & GOSSIP_STORE_MINOR_VERSION_MASK)
|
||||
|
||||
/**
|
||||
* Bit of length we use to mark a deleted record.
|
||||
* Bit of flags we use to mark a deleted record.
|
||||
*/
|
||||
#define GOSSIP_STORE_LEN_DELETED_BIT 0x80000000U
|
||||
#define GOSSIP_STORE_DELETED_BIT 0x8000U
|
||||
|
||||
/**
|
||||
* Bit of length we use to mark an important record.
|
||||
* Bit of flags we use to mark an important record.
|
||||
*/
|
||||
#define GOSSIP_STORE_LEN_PUSH_BIT 0x40000000U
|
||||
#define GOSSIP_STORE_PUSH_BIT 0x4000U
|
||||
|
||||
/**
|
||||
* Bit of length used to define a rate-limited record (do not rebroadcast)
|
||||
* Bit of flags used to define a rate-limited record (do not rebroadcast)
|
||||
*/
|
||||
#define GOSSIP_STORE_LEN_RATELIMIT_BIT 0x20000000U
|
||||
#define GOSSIP_STORE_RATELIMIT_BIT 0x2000U
|
||||
|
||||
/**
|
||||
* Bit used to mark a channel announcement as inactive (needs channel updates.)
|
||||
* Bit of flags used to mark a channel announcement as inactive (needs channel updates.)
|
||||
*/
|
||||
#define GOSSIP_STORE_LEN_ZOMBIE_BIT 0x10000000U
|
||||
#define GOSSIP_STORE_ZOMBIE_BIT 0x1000U
|
||||
|
||||
/**
|
||||
* Full flags mask
|
||||
*/
|
||||
#define GOSSIP_STORE_FLAGS_MASK 0xFFFF0000U
|
||||
|
||||
/* Mask for extracting just the length part of len field */
|
||||
#define GOSSIP_STORE_LEN_MASK \
|
||||
(~(GOSSIP_STORE_FLAGS_MASK))
|
||||
|
||||
/**
|
||||
* gossip_hdr -- On-disk format header.
|
||||
*/
|
||||
struct gossip_hdr {
|
||||
beint32_t len; /* Length of message after header. */
|
||||
beint16_t flags; /* Length of message after header. */
|
||||
beint16_t len; /* Length of message after header. */
|
||||
beint32_t crc; /* crc of message of timestamp, after header. */
|
||||
beint32_t timestamp; /* timestamp of msg. */
|
||||
};
|
||||
|
@ -611,16 +611,16 @@ static bool map_catchup(struct gossmap *map, size_t *num_rejected)
|
||||
map->map_end += reclen) {
|
||||
struct gossip_hdr ghdr;
|
||||
size_t off;
|
||||
u16 type;
|
||||
u16 type, flags;
|
||||
|
||||
map_copy(map, map->map_end, &ghdr, sizeof(ghdr));
|
||||
reclen = (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_MASK)
|
||||
+ sizeof(ghdr);
|
||||
reclen = be16_to_cpu(ghdr.len) + sizeof(ghdr);
|
||||
|
||||
if (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_DELETED_BIT)
|
||||
flags = be16_to_cpu(ghdr.flags);
|
||||
if (flags & GOSSIP_STORE_DELETED_BIT)
|
||||
continue;
|
||||
|
||||
if (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_ZOMBIE_BIT)
|
||||
if (flags & GOSSIP_STORE_ZOMBIE_BIT)
|
||||
continue;
|
||||
|
||||
/* Partial write, this can happen. */
|
||||
@ -1014,7 +1014,7 @@ bool gossmap_chan_get_capacity(const struct gossmap *map,
|
||||
/* Skip over this record to next; expect a gossip_store_channel_amount */
|
||||
off = c->cann_off - sizeof(ghdr);
|
||||
map_copy(map, off, &ghdr, sizeof(ghdr));
|
||||
off += sizeof(ghdr) + (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_MASK);
|
||||
off += sizeof(ghdr) + be16_to_cpu(ghdr.len);
|
||||
|
||||
/* Partial write, this can happen. */
|
||||
if (off + sizeof(ghdr) + 2 > map->map_size)
|
||||
@ -1128,7 +1128,7 @@ u8 *gossmap_chan_get_announce(const tal_t *ctx,
|
||||
const struct gossmap *map,
|
||||
const struct gossmap_chan *c)
|
||||
{
|
||||
u32 len;
|
||||
u16 len;
|
||||
u8 *msg;
|
||||
u32 pre_off;
|
||||
|
||||
@ -1137,7 +1137,8 @@ u8 *gossmap_chan_get_announce(const tal_t *ctx,
|
||||
pre_off = 2 + 8 + 2 + sizeof(struct gossip_hdr);
|
||||
else
|
||||
pre_off = sizeof(struct gossip_hdr);
|
||||
len = (map_be32(map, c->cann_off - pre_off) & GOSSIP_STORE_LEN_MASK);
|
||||
len = map_be16(map, c->cann_off - pre_off
|
||||
+ offsetof(struct gossip_hdr, len));
|
||||
|
||||
msg = tal_arr(ctx, u8, len);
|
||||
map_copy(map, c->cann_off, msg, len);
|
||||
@ -1149,14 +1150,14 @@ u8 *gossmap_node_get_announce(const tal_t *ctx,
|
||||
const struct gossmap *map,
|
||||
const struct gossmap_node *n)
|
||||
{
|
||||
u32 len;
|
||||
u16 len;
|
||||
u8 *msg;
|
||||
|
||||
if (n->nann_off == 0)
|
||||
return NULL;
|
||||
|
||||
len = (map_be32(map, n->nann_off - sizeof(struct gossip_hdr))
|
||||
& GOSSIP_STORE_LEN_MASK);
|
||||
len = map_be16(map, n->nann_off - sizeof(struct gossip_hdr)
|
||||
+ offsetof(struct gossip_hdr, len));
|
||||
msg = tal_arr(ctx, u8, len);
|
||||
|
||||
map_copy(map, n->nann_off, msg, len);
|
||||
|
@ -51,7 +51,8 @@ static void write_to_store(int store_fd, const u8 *msg)
|
||||
{
|
||||
struct gossip_hdr hdr;
|
||||
|
||||
hdr.len = cpu_to_be32(tal_count(msg));
|
||||
hdr.flags = cpu_to_be16(0);
|
||||
hdr.len = cpu_to_be16(tal_count(msg));
|
||||
/* We don't actually check these! */
|
||||
hdr.crc = 0;
|
||||
hdr.timestamp = 0;
|
||||
|
@ -44,7 +44,8 @@ static void write_to_store(int store_fd, const u8 *msg)
|
||||
{
|
||||
struct gossip_hdr hdr;
|
||||
|
||||
hdr.len = cpu_to_be32(tal_count(msg));
|
||||
hdr.flags = cpu_to_be16(0);
|
||||
hdr.len = cpu_to_be16(tal_count(msg));
|
||||
/* We don't actually check these! */
|
||||
hdr.crc = 0;
|
||||
hdr.timestamp = 0;
|
||||
|
@ -65,17 +65,17 @@ int main(int argc, char *argv[])
|
||||
while (read(fd, &hdr, sizeof(hdr)) == sizeof(hdr)) {
|
||||
struct amount_sat sat;
|
||||
struct short_channel_id scid;
|
||||
u32 msglen = be32_to_cpu(hdr.len);
|
||||
u16 flags = be16_to_cpu(hdr.flags);
|
||||
u16 msglen = be16_to_cpu(hdr.len);
|
||||
u8 *msg, *inner;
|
||||
bool deleted, push, ratelimit, zombie;
|
||||
u32 blockheight;
|
||||
|
||||
deleted = (msglen & GOSSIP_STORE_LEN_DELETED_BIT);
|
||||
push = (msglen & GOSSIP_STORE_LEN_PUSH_BIT);
|
||||
ratelimit = (msglen & GOSSIP_STORE_LEN_RATELIMIT_BIT);
|
||||
zombie = (msglen & GOSSIP_STORE_LEN_ZOMBIE_BIT);
|
||||
deleted = (flags & GOSSIP_STORE_DELETED_BIT);
|
||||
push = (flags & GOSSIP_STORE_PUSH_BIT);
|
||||
ratelimit = (flags & GOSSIP_STORE_RATELIMIT_BIT);
|
||||
zombie = (msglen & GOSSIP_STORE_ZOMBIE_BIT);
|
||||
|
||||
msglen &= GOSSIP_STORE_LEN_MASK;
|
||||
msg = tal_arr(NULL, u8, msglen);
|
||||
if (read(fd, msg, msglen) != msglen)
|
||||
errx(1, "%zu: Truncated file?", off);
|
||||
|
@ -83,13 +83,14 @@ static bool append_msg(int fd, const u8 *msg, u32 timestamp,
|
||||
assert(*len);
|
||||
|
||||
msglen = tal_count(msg);
|
||||
hdr.len = cpu_to_be32(msglen);
|
||||
hdr.len = cpu_to_be16(msglen);
|
||||
hdr.flags = 0;
|
||||
if (push)
|
||||
hdr.len |= CPU_TO_BE32(GOSSIP_STORE_LEN_PUSH_BIT);
|
||||
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_PUSH_BIT);
|
||||
if (spam)
|
||||
hdr.len |= CPU_TO_BE32(GOSSIP_STORE_LEN_RATELIMIT_BIT);
|
||||
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_RATELIMIT_BIT);
|
||||
if (zombie)
|
||||
hdr.len |= CPU_TO_BE32(GOSSIP_STORE_LEN_ZOMBIE_BIT);
|
||||
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_ZOMBIE_BIT);
|
||||
hdr.crc = cpu_to_be32(crc32c(timestamp, msg, msglen));
|
||||
hdr.timestamp = cpu_to_be32(timestamp);
|
||||
|
||||
@ -175,7 +176,7 @@ static u32 gossip_store_compact_offline(struct routing_state *rstate)
|
||||
size_t msglen;
|
||||
u8 *msg;
|
||||
|
||||
msglen = (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK);
|
||||
msglen = be16_to_cpu(hdr.len);
|
||||
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",
|
||||
@ -184,7 +185,7 @@ static u32 gossip_store_compact_offline(struct routing_state *rstate)
|
||||
goto close_and_delete;
|
||||
}
|
||||
|
||||
if (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) {
|
||||
if (be16_to_cpu(hdr.flags) & GOSSIP_STORE_DELETED_BIT) {
|
||||
deleted++;
|
||||
tal_free(msg);
|
||||
continue;
|
||||
@ -214,7 +215,7 @@ static u32 gossip_store_compact_offline(struct routing_state *rstate)
|
||||
|
||||
/* Recalc msglen and header */
|
||||
msglen = tal_bytelen(msg);
|
||||
hdr.len = cpu_to_be32(msglen);
|
||||
hdr.len = cpu_to_be16(msglen);
|
||||
hdr.crc = cpu_to_be32(crc32c(be32_to_cpu(hdr.timestamp),
|
||||
msg, msglen));
|
||||
}
|
||||
@ -317,7 +318,7 @@ static size_t transfer_store_msg(int from_fd, size_t from_off,
|
||||
int *type)
|
||||
{
|
||||
struct gossip_hdr hdr;
|
||||
u32 msglen;
|
||||
u16 flags, msglen;
|
||||
u8 *msg;
|
||||
const u8 *p;
|
||||
size_t tmplen;
|
||||
@ -330,15 +331,14 @@ static size_t transfer_store_msg(int from_fd, size_t from_off,
|
||||
return 0;
|
||||
}
|
||||
|
||||
msglen = be32_to_cpu(hdr.len);
|
||||
if (msglen & GOSSIP_STORE_LEN_DELETED_BIT) {
|
||||
flags = be16_to_cpu(hdr.flags);
|
||||
if (flags & GOSSIP_STORE_DELETED_BIT) {
|
||||
status_broken("Can't transfer deleted msg from gossip store @%zu",
|
||||
from_off);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ignore any non-length bits (e.g. push) */
|
||||
msglen &= GOSSIP_STORE_LEN_MASK;
|
||||
msglen = be16_to_cpu(hdr.len);
|
||||
|
||||
/* FIXME: Reuse buffer? */
|
||||
msg = tal_arr(tmpctx, u8, sizeof(hdr) + msglen);
|
||||
@ -454,11 +454,12 @@ bool gossip_store_compact(struct gossip_store *gs)
|
||||
/* Start by writing all channel announcements and updates. */
|
||||
off = 1;
|
||||
while (pread(gs->fd, &hdr, sizeof(hdr), off) == sizeof(hdr)) {
|
||||
u32 msglen, wlen;
|
||||
u16 msglen;
|
||||
u32 wlen;
|
||||
int msgtype;
|
||||
|
||||
msglen = (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK);
|
||||
if (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) {
|
||||
msglen = be16_to_cpu(hdr.len);
|
||||
if (be16_to_cpu(hdr.flags) & GOSSIP_STORE_DELETED_BIT) {
|
||||
off += sizeof(hdr) + msglen;
|
||||
deleted++;
|
||||
continue;
|
||||
@ -588,7 +589,10 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update)
|
||||
/* Returns index of following entry. */
|
||||
static u32 delete_by_index(struct gossip_store *gs, u32 index, int type)
|
||||
{
|
||||
beint32_t belen;
|
||||
struct {
|
||||
beint16_t beflags;
|
||||
beint16_t belen;
|
||||
} hdr;
|
||||
|
||||
/* Should never get here during loading! */
|
||||
assert(gs->writable);
|
||||
@ -601,21 +605,20 @@ static u32 delete_by_index(struct gossip_store *gs, u32 index, int type)
|
||||
assert(fromwire_peektype(msg) == type);
|
||||
#endif
|
||||
|
||||
if (pread(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
if (pread(gs->fd, &hdr, sizeof(hdr), index) != sizeof(hdr))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed reading len to delete @%u: %s",
|
||||
"Failed reading flags & len to delete @%u: %s",
|
||||
index, strerror(errno));
|
||||
|
||||
assert((be32_to_cpu(belen) & GOSSIP_STORE_LEN_DELETED_BIT) == 0);
|
||||
belen |= cpu_to_be32(GOSSIP_STORE_LEN_DELETED_BIT);
|
||||
if (pwrite(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
assert((be16_to_cpu(hdr.beflags) & GOSSIP_STORE_DELETED_BIT) == 0);
|
||||
hdr.beflags |= cpu_to_be16(GOSSIP_STORE_DELETED_BIT);
|
||||
if (pwrite(gs->fd, &hdr.beflags, sizeof(hdr.beflags), index) != sizeof(hdr.beflags))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed writing len to delete @%u: %s",
|
||||
"Failed writing flags to delete @%u: %s",
|
||||
index, strerror(errno));
|
||||
gs->deleted++;
|
||||
|
||||
return index + sizeof(struct gossip_hdr)
|
||||
+ (be32_to_cpu(belen) & GOSSIP_STORE_LEN_MASK);
|
||||
return index + sizeof(struct gossip_hdr) + be16_to_cpu(hdr.belen);
|
||||
}
|
||||
|
||||
void gossip_store_delete(struct gossip_store *gs,
|
||||
@ -645,94 +648,59 @@ void gossip_store_mark_channel_deleted(struct gossip_store *gs,
|
||||
0, false, false, false, NULL);
|
||||
}
|
||||
|
||||
/* Marks the length field of a channel_announcement with the zombie flag bit */
|
||||
void gossip_store_mark_channel_zombie(struct gossip_store *gs,
|
||||
struct broadcastable *bcast)
|
||||
static void mark_zombie(struct gossip_store *gs,
|
||||
const struct broadcastable *bcast,
|
||||
enum peer_wire expected_type)
|
||||
{
|
||||
beint32_t belen;
|
||||
beint16_t beflags;
|
||||
u32 index = bcast->index;
|
||||
|
||||
/* We assume flags is the first field! */
|
||||
BUILD_ASSERT(offsetof(struct gossip_hdr, flags) == 0);
|
||||
|
||||
/* Should never get here during loading! */
|
||||
assert(gs->writable);
|
||||
|
||||
assert(index);
|
||||
|
||||
#if DEVELOPER
|
||||
const u8 *msg = gossip_store_get(tmpctx, gs, index);
|
||||
assert(fromwire_peektype(msg) == WIRE_CHANNEL_ANNOUNCEMENT);
|
||||
assert(fromwire_peektype(msg) == expected_type);
|
||||
#endif
|
||||
|
||||
if (pread(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
if (pread(gs->fd, &beflags, sizeof(beflags), index) != sizeof(beflags))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed reading len to zombie channel @%u: %s",
|
||||
"Failed reading flags to zombie %s @%u: %s",
|
||||
peer_wire_name(expected_type),
|
||||
index, strerror(errno));
|
||||
|
||||
assert((be32_to_cpu(belen) & GOSSIP_STORE_LEN_DELETED_BIT) == 0);
|
||||
belen |= cpu_to_be32(GOSSIP_STORE_LEN_ZOMBIE_BIT);
|
||||
if (pwrite(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
assert((be16_to_cpu(beflags) & GOSSIP_STORE_DELETED_BIT) == 0);
|
||||
beflags |= cpu_to_be16(GOSSIP_STORE_ZOMBIE_BIT);
|
||||
if (pwrite(gs->fd, &beflags, sizeof(beflags), index) != sizeof(beflags))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed writing len to zombie channel @%u: %s",
|
||||
"Failed writing flags to zombie %s @%u: %s",
|
||||
peer_wire_name(expected_type),
|
||||
index, strerror(errno));
|
||||
}
|
||||
|
||||
/* Marks the length field of a channel_announcement with the zombie flag bit */
|
||||
void gossip_store_mark_channel_zombie(struct gossip_store *gs,
|
||||
struct broadcastable *bcast)
|
||||
{
|
||||
mark_zombie(gs, bcast, WIRE_CHANNEL_ANNOUNCEMENT);
|
||||
}
|
||||
|
||||
/* Marks the length field of a channel_update with the zombie flag bit */
|
||||
void gossip_store_mark_cupdate_zombie(struct gossip_store *gs,
|
||||
struct broadcastable *bcast)
|
||||
{
|
||||
beint32_t belen;
|
||||
u32 index = bcast->index;
|
||||
|
||||
/* Should never get here during loading! */
|
||||
assert(gs->writable);
|
||||
|
||||
assert(index);
|
||||
|
||||
#if DEVELOPER
|
||||
const u8 *msg = gossip_store_get(tmpctx, gs, index);
|
||||
assert(fromwire_peektype(msg) == WIRE_CHANNEL_UPDATE);
|
||||
#endif
|
||||
|
||||
if (pread(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed reading len to zombie channel update @%u: %s",
|
||||
index, strerror(errno));
|
||||
|
||||
assert((be32_to_cpu(belen) & GOSSIP_STORE_LEN_DELETED_BIT) == 0);
|
||||
belen |= cpu_to_be32(GOSSIP_STORE_LEN_ZOMBIE_BIT);
|
||||
if (pwrite(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed writing len to zombie channel update @%u: %s",
|
||||
index, strerror(errno));
|
||||
mark_zombie(gs, bcast, WIRE_CHANNEL_UPDATE);
|
||||
}
|
||||
|
||||
/* Marks the length field of a node_announcement with the zombie flag bit */
|
||||
void gossip_store_mark_nannounce_zombie(struct gossip_store *gs,
|
||||
struct broadcastable *bcast)
|
||||
{
|
||||
beint32_t belen;
|
||||
u32 index = bcast->index;
|
||||
|
||||
/* Should never get here during loading! */
|
||||
assert(gs->writable);
|
||||
|
||||
assert(index);
|
||||
|
||||
#if DEVELOPER
|
||||
const u8 *msg = gossip_store_get(tmpctx, gs, index);
|
||||
assert(fromwire_peektype(msg) == WIRE_NODE_ANNOUNCEMENT);
|
||||
#endif
|
||||
|
||||
if (pread(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed reading len to zombie node announcement @%u: %s",
|
||||
index, strerror(errno));
|
||||
|
||||
assert((be32_to_cpu(belen) & GOSSIP_STORE_LEN_DELETED_BIT) == 0);
|
||||
belen |= cpu_to_be32(GOSSIP_STORE_LEN_ZOMBIE_BIT);
|
||||
if (pwrite(gs->fd, &belen, sizeof(belen), index) != sizeof(belen))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Failed writing len to zombie channel update @%u: %s",
|
||||
index, strerror(errno));
|
||||
mark_zombie(gs, bcast, WIRE_NODE_ANNOUNCEMENT);
|
||||
}
|
||||
|
||||
const u8 *gossip_store_get(const tal_t *ctx,
|
||||
@ -754,13 +722,13 @@ const u8 *gossip_store_get(const tal_t *ctx,
|
||||
offset, gs->len, strerror(errno));
|
||||
}
|
||||
|
||||
if (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT)
|
||||
if (be16_to_cpu(hdr.flags) & GOSSIP_STORE_DELETED_BIT)
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"gossip_store: get delete entry offset %"PRIu64
|
||||
"/%"PRIu64"",
|
||||
offset, gs->len);
|
||||
|
||||
msglen = (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_MASK);
|
||||
msglen = be16_to_cpu(hdr.len);
|
||||
checksum = be32_to_cpu(hdr.crc);
|
||||
msg = tal_arr(ctx, u8, msglen);
|
||||
if (pread(gs->fd, msg, msglen, offset + sizeof(hdr)) != msglen)
|
||||
@ -816,7 +784,9 @@ 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_MASK;
|
||||
bool spam;
|
||||
|
||||
msglen = be16_to_cpu(hdr.len);
|
||||
checksum = be32_to_cpu(hdr.crc);
|
||||
msg = tal_arr(tmpctx, u8, msglen);
|
||||
|
||||
@ -832,12 +802,13 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
}
|
||||
|
||||
/* Skip deleted entries */
|
||||
if (be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) {
|
||||
if (be16_to_cpu(hdr.flags) & GOSSIP_STORE_DELETED_BIT) {
|
||||
/* Count includes deleted! */
|
||||
gs->count++;
|
||||
gs->deleted++;
|
||||
goto next;
|
||||
}
|
||||
spam = (be16_to_cpu(hdr.flags) & GOSSIP_STORE_RATELIMIT_BIT);
|
||||
|
||||
switch (fromwire_peektype(msg)) {
|
||||
case WIRE_GOSSIP_STORE_PRIVATE_CHANNEL: {
|
||||
@ -908,8 +879,7 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
case WIRE_CHANNEL_UPDATE:
|
||||
if (!routing_add_channel_update(rstate,
|
||||
take(msg), gs->len,
|
||||
NULL, false,
|
||||
be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_RATELIMIT_BIT)) {
|
||||
NULL, false, spam)) {
|
||||
bad = "Bad channel_update";
|
||||
goto badmsg;
|
||||
}
|
||||
@ -918,8 +888,7 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
|
||||
case WIRE_NODE_ANNOUNCEMENT:
|
||||
if (!routing_add_node_announcement(rstate,
|
||||
take(msg), gs->len,
|
||||
NULL, NULL,
|
||||
be32_to_cpu(hdr.len) & GOSSIP_STORE_LEN_RATELIMIT_BIT)) {
|
||||
NULL, NULL, spam)) {
|
||||
bad = "Bad node_announcement";
|
||||
goto badmsg;
|
||||
}
|
||||
|
@ -244,7 +244,8 @@ static void write_to_store(int store_fd, const u8 *msg)
|
||||
{
|
||||
struct gossip_hdr hdr;
|
||||
|
||||
hdr.len = cpu_to_be32(tal_count(msg));
|
||||
hdr.flags = cpu_to_be16(0);
|
||||
hdr.len = cpu_to_be16(tal_count(msg));
|
||||
/* We don't actually check these! */
|
||||
hdr.crc = 0;
|
||||
hdr.timestamp = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user