Skip to content

Commit

Permalink
gossipd: remove zombie handling.
Browse files Browse the repository at this point in the history
We never enabled it, because we seemed to be eliminating valid
channels.  We discard zombie-marked records on loading.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
  • Loading branch information
rustyrussell committed Feb 3, 2024
1 parent af64d30 commit e7ceffd
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 276 deletions.
5 changes: 0 additions & 5 deletions common/gossip_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,6 @@ struct gossip_rcvd_filter;
*/
#define GOSSIP_STORE_RATELIMIT_BIT 0x2000U

/**
* Bit of flags used to mark a channel announcement as inactive (needs channel updates.)
*/
#define GOSSIP_STORE_ZOMBIE_BIT 0x1000U

/**
* Bit of flags used to mark a channel announcement closed (not deleted for 12 blocks)
*/
Expand Down
3 changes: 0 additions & 3 deletions common/gossmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,9 +651,6 @@ static bool map_catchup(struct gossmap *map, bool *changed)
if (flags & GOSSIP_STORE_DELETED_BIT)
continue;

if (flags & GOSSIP_STORE_ZOMBIE_BIT)
continue;

/* Partial write, this can happen. */
if (map->map_end + reclen > map->map_size)
break;
Expand Down
4 changes: 0 additions & 4 deletions contrib/pyln-client/pyln/client/gossmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
GOSSIP_STORE_LEN_DELETED_BIT = 0x8000
GOSSIP_STORE_LEN_PUSH_BIT = 0x4000
GOSSIP_STORE_LEN_RATELIMIT_BIT = 0x2000
GOSSIP_STORE_ZOMBIE_BIT = 0x1000

# These duplicate constants in lightning/gossipd/gossip_store_wiregen.h
WIRE_GOSSIP_STORE_PRIVATE_CHANNEL = 4104
Expand Down Expand Up @@ -92,7 +91,6 @@ def __init__(self, buf: bytes, off: int):
self.off = off
self.deleted = (self.flags & GOSSIP_STORE_LEN_DELETED_BIT) != 0
self.ratelimit = (self.flags & GOSSIP_STORE_LEN_RATELIMIT_BIT) != 0
self.zombie = (self.flags & GOSSIP_STORE_ZOMBIE_BIT) != 0


class GossmapHalfchannel(object):
Expand Down Expand Up @@ -624,8 +622,6 @@ def refresh(self):
break
if hdr.deleted: # Skip deleted records
continue
if hdr.zombie:
continue

rectype, = struct.unpack(">H", rec[:2])
if rectype == channel_announcement.number:
Expand Down
6 changes: 2 additions & 4 deletions devtools/dump-gossipstore.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,12 @@ int main(int argc, char *argv[])
u16 flags = be16_to_cpu(hdr.flags);
u16 msglen = be16_to_cpu(hdr.len);
u8 *msg, *inner;
bool deleted, push, ratelimit, zombie, dying;
bool deleted, push, ratelimit, dying;
u32 blockheight;

deleted = (flags & GOSSIP_STORE_DELETED_BIT);
push = (flags & GOSSIP_STORE_PUSH_BIT);
ratelimit = (flags & GOSSIP_STORE_RATELIMIT_BIT);
zombie = (flags & GOSSIP_STORE_ZOMBIE_BIT);
dying = (flags & GOSSIP_STORE_DYING_BIT);

msg = tal_arr(NULL, u8, msglen);
Expand All @@ -85,11 +84,10 @@ int main(int argc, char *argv[])
!= crc32c(be32_to_cpu(hdr.timestamp), msg, msglen))
warnx("Checksum verification failed");

printf("%zu: %s%s%s%s%s", off,
printf("%zu: %s%s%s%s", off,
deleted ? "DELETED " : "",
push ? "PUSH " : "",
ratelimit ? "RATE-LIMITED " : "",
zombie ? "ZOMBIE " : "",
dying ? "DYING " : "");
if (print_timestamp)
printf("T=%u ", be32_to_cpu(hdr.timestamp));
Expand Down
82 changes: 23 additions & 59 deletions gossipd/gossip_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
#include <unistd.h>
#include <wire/peer_wire.h>

/* Obsolete ZOMBIE bit */
#define GOSSIP_STORE_ZOMBIE_BIT_V13 0x1000U

#define GOSSIP_STORE_TEMP_FILENAME "gossip_store.tmp"
/* We write it as major version 0, minor version 13 */
#define GOSSIP_STORE_VER ((0 << 5) | 13)
/* We write it as major version 0, minor version 14 */
#define GOSSIP_STORE_VER ((0 << 5) | 14)

struct gossip_store {
/* Back pointer. */
Expand Down Expand Up @@ -59,7 +62,7 @@ static ssize_t gossip_pwritev(int fd, const struct iovec *iov, int iovcnt,
#endif /* !HAVE_PWRITEV */

static bool append_msg(int fd, const u8 *msg, u32 timestamp,
bool zombie, bool spam, bool dying, u64 *len)
bool spam, bool dying, u64 *len)
{
struct gossip_hdr hdr;
u32 msglen;
Expand All @@ -73,8 +76,6 @@ static bool append_msg(int fd, const u8 *msg, u32 timestamp,
hdr.flags = 0;
if (spam)
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_RATELIMIT_BIT);
if (zombie)
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_ZOMBIE_BIT);
if (dying)
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_DYING_BIT);
hdr.crc = cpu_to_be32(crc32c(timestamp, msg, msglen));
Expand All @@ -97,10 +98,11 @@ static bool append_msg(int fd, const u8 *msg, u32 timestamp,
* v11 mandated channel_updates use the htlc_maximum_msat field
* v12 added the zombie flag for expired channel updates
* v13 removed private gossip entries
* v14 removed zombie flags
*/
static bool can_upgrade(u8 oldversion)
{
return oldversion >= 9 && oldversion <= 12;
return oldversion >= 9 && oldversion <= 13;
}

/* On upgrade, do best effort on private channels: hand them to
Expand Down Expand Up @@ -154,6 +156,7 @@ static void give_lightningd_canned_private_update(struct daemon *daemon,

static bool upgrade_field(u8 oldversion,
struct daemon *daemon,
u16 hdr_flags,
u8 **msg)
{
int type = fromwire_peektype(*msg);
Expand All @@ -175,6 +178,12 @@ static bool upgrade_field(u8 oldversion,
*msg = tal_free(*msg);
}
}
if (oldversion <= 13) {
/* Discard any zombies */
if (hdr_flags & GOSSIP_STORE_ZOMBIE_BIT_V13) {
*msg = tal_free(*msg);
}
}

return true;
}
Expand Down Expand Up @@ -250,7 +259,8 @@ static u32 gossip_store_compact_offline(struct daemon *daemon)
}

if (oldversion != version) {
if (!upgrade_field(oldversion, daemon, &msg)) {
if (!upgrade_field(oldversion, daemon,
be16_to_cpu(hdr.flags), &msg)) {
tal_free(msg);
goto close_and_delete;
}
Expand Down Expand Up @@ -299,7 +309,7 @@ static u32 gossip_store_compact_offline(struct daemon *daemon)
oldlen = lseek(old_fd, SEEK_END, 0);
newlen = lseek(new_fd, SEEK_END, 0);
append_msg(old_fd, towire_gossip_store_ended(tmpctx, newlen),
0, false, false, false, &oldlen);
0, false, false, &oldlen);
close(old_fd);
status_debug("gossip_store_compact_offline: %zu deleted, %zu copied",
deleted, count);
Expand Down Expand Up @@ -357,20 +367,20 @@ struct gossip_store *gossip_store_new(struct daemon *daemon)
}

u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
u32 timestamp, bool zombie,
u32 timestamp,
bool spam, bool dying, const u8 *addendum)
{
u64 off = gs->len;

/* Should never get here during loading! */
assert(gs->writable);

if (!append_msg(gs->fd, gossip_msg, timestamp, zombie, spam, dying, &gs->len)) {
if (!append_msg(gs->fd, gossip_msg, timestamp, spam, dying, &gs->len)) {
status_broken("Failed writing to gossip store: %s",
strerror(errno));
return 0;
}
if (addendum && !append_msg(gs->fd, addendum, 0, false, false, false, &gs->len)) {
if (addendum && !append_msg(gs->fd, addendum, 0, false, false, &gs->len)) {
status_broken("Failed writing addendum to gossip store: %s",
strerror(errno));
return 0;
Expand Down Expand Up @@ -504,53 +514,7 @@ void gossip_store_mark_channel_deleted(struct gossip_store *gs,
const struct short_channel_id *scid)
{
gossip_store_add(gs, towire_gossip_store_delete_chan(tmpctx, scid),
0, false, false, false, NULL);
}

static void mark_zombie(struct gossip_store *gs,
const struct broadcastable *bcast,
enum peer_wire expected_type)
{
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);

const u8 *msg = gossip_store_get(tmpctx, gs, index);
assert(fromwire_peektype(msg) == expected_type);

if (pread(gs->fd, &beflags, sizeof(beflags), index) != sizeof(beflags))
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"Failed reading flags to zombie %s @%u: %s",
peer_wire_name(expected_type),
index, strerror(errno));

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 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)
{
mark_zombie(gs, bcast, WIRE_CHANNEL_UPDATE);
0, false, false, NULL);
}

u32 gossip_store_get_timestamp(struct gossip_store *gs, u64 offset)
Expand Down Expand Up @@ -737,7 +701,7 @@ u32 gossip_store_load(struct gossip_store *gs)
if (!routing_add_channel_update(gs->daemon->rstate,
take(msg), gs->len,
NULL, false,
spam, false)) {
spam)) {
bad = "Bad channel_update";
goto badmsg;
}
Expand Down
14 changes: 1 addition & 13 deletions gossipd/gossip_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,13 @@ u32 gossip_store_load(struct gossip_store *gs);
* @gs: gossip store
* @gossip_msg: the gossip message to insert.
* @timestamp: the timestamp for filtering of this messsage.
* @zombie: true if this channel is missing a current channel_update.
* @spam: true if this message is rate-limited and squelched to peers.
* @dying: true if this message is for a dying channel.
* @addendum: another message to append immediately after this
* (for appending amounts to channel_announcements for internal use).
*/
u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
u32 timestamp, bool zombie, bool spam, bool dying,
u32 timestamp, bool spam, bool dying,
const u8 *addendum);


Expand Down Expand Up @@ -80,17 +79,6 @@ void gossip_store_flag(struct gossip_store *gs,
void gossip_store_mark_channel_deleted(struct gossip_store *gs,
const struct short_channel_id *scid);

/*
* Marks the length field of a channel announcement with a zombie flag bit.
* This allows the channel_announcement to be retained in the store while
* waiting for channel updates to reactivate it.
*/
void gossip_store_mark_channel_zombie(struct gossip_store *gs,
struct broadcastable *bcast);

void gossip_store_mark_cupdate_zombie(struct gossip_store *gs,
struct broadcastable *bcast);

/**
* Mark this channel_announcement/channel_update as dying.
*
Expand Down
Loading

0 comments on commit e7ceffd

Please sign in to comment.