Skip to content

Commit

Permalink
gossipd: remove spam handling.
Browse files Browse the repository at this point in the history
We weakened this progressively over time, and gossip v1.5 makes spam
impossible by protocol, so we can wait until then.

Removing this code simplifies things a great deal!

Signed-off-by: Rusty Russell <[email protected]>
Changelog-Removed: Protocol: we no longer ratelimit gossip messages by channel, making our code far simpler.
  • Loading branch information
rustyrussell committed Feb 3, 2024
1 parent e7ceffd commit 07cd4a8
Show file tree
Hide file tree
Showing 13 changed files with 53 additions and 421 deletions.
5 changes: 0 additions & 5 deletions common/gossip_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,6 @@ struct gossip_rcvd_filter;
*/
#define GOSSIP_STORE_PUSH_BIT 0x4000U

/**
* Bit of flags used to define a rate-limited record (do not rebroadcast)
*/
#define GOSSIP_STORE_RATELIMIT_BIT 0x2000U

/**
* Bit of flags used to mark a channel announcement closed (not deleted for 12 blocks)
*/
Expand Down
5 changes: 0 additions & 5 deletions connectd/gossip_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ static bool public_msg_type(enum peer_wire type)
u8 *gossip_store_next(const tal_t *ctx,
int *gossip_store_fd,
u32 timestamp_min, u32 timestamp_max,
bool with_spam,
size_t *off, size_t *end)
{
u8 *msg = NULL;
Expand All @@ -122,7 +121,6 @@ u8 *gossip_store_next(const tal_t *ctx,
struct gossip_hdr hdr;
u16 msglen, flags;
u32 checksum, timestamp;
bool ratelimited;
int type, r;

r = pread(*gossip_store_fd, &hdr, sizeof(hdr), *off);
Expand All @@ -131,7 +129,6 @@ u8 *gossip_store_next(const tal_t *ctx,

msglen = be16_to_cpu(hdr.len);
flags = be16_to_cpu(hdr.flags);
ratelimited = (flags & GOSSIP_STORE_RATELIMIT_BIT);

/* Skip any deleted/dying entries. */
if (flags & (GOSSIP_STORE_DELETED_BIT|GOSSIP_STORE_DYING_BIT)) {
Expand Down Expand Up @@ -172,8 +169,6 @@ u8 *gossip_store_next(const tal_t *ctx,
/* Ignore gossipd internal messages. */
} else if (!public_msg_type(type)) {
msg = tal_free(msg);
} else if (!with_spam && ratelimited) {
msg = tal_free(msg);
}
}

Expand Down
1 change: 0 additions & 1 deletion connectd/gossip_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
u8 *gossip_store_next(const tal_t *ctx,
int *gossip_store_fd,
u32 timestamp_min, u32 timestamp_max,
bool with_spam,
size_t *off, size_t *end);

/**
Expand Down
1 change: 0 additions & 1 deletion connectd/multiplex.c
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ static u8 *maybe_from_gossip_store(const tal_t *ctx, struct peer *peer)
msg = gossip_store_next(ctx, &peer->daemon->gossip_store_fd,
peer->gs.timestamp_min,
peer->gs.timestamp_max,
false,
&peer->gs.off,
&peer->daemon->gossip_store_end);
/* Don't send back gossip they sent to us! */
Expand Down
1 change: 0 additions & 1 deletion contrib/pyln-client/pyln/client/gossmap.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
GOSSIP_STORE_MAJOR_VERSION_MASK = 0xE0
GOSSIP_STORE_LEN_DELETED_BIT = 0x8000
GOSSIP_STORE_LEN_PUSH_BIT = 0x4000
GOSSIP_STORE_LEN_RATELIMIT_BIT = 0x2000

# These duplicate constants in lightning/gossipd/gossip_store_wiregen.h
WIRE_GOSSIP_STORE_PRIVATE_CHANNEL = 4104
Expand Down
8 changes: 0 additions & 8 deletions contrib/pyln-client/pyln/client/gossmapstats.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ def filter_halfchannels(self, predicate: Callable[[GossmapHalfchannel], bool], c
return hc0 + hc1

# Now a bunch of predefined specific filter methods
def filter_nodes_ratelimited(self, nodes: Optional[Iterable[GossmapNode]] = None) -> List[GossmapNode]:
""" Filters nodes being marked by cln as ratelimited, when they send out too many updates. """
return self.filter_nodes(lambda n: n.hdr is not None and n.hdr.ratelimit, nodes)

def filter_nodes_unannounced(self, nodes: Optional[Iterable[GossmapNode]] = None) -> List[GossmapNode]:
""" Filters nodes that are only known by a channel, i.e. missing a node_announcement.
Usually happens when a peer has been offline for a while. """
Expand Down Expand Up @@ -124,10 +120,6 @@ def filter_halfchannels_disabled(self, channels: Optional[Iterable[GossmapChanne
""" Filters half-channels that are disabled. """
return self.filter_halfchannels(lambda hc: hc.disabled, channels)

def filter_halfchannels_ratelimited(self, channels: Optional[Iterable[GossmapChannel]] = None) -> List[GossmapHalfchannel]:
""" Filters half-channels that are being marked as ratelimited for sending out too many updates. """
return self.filter_halfchannels(lambda hc: hc.hdr.ratelimit, channels)

def quantiles_nodes_channel_count(self, tiles=100, nodes: Optional[Iterable[GossmapNode]] = None) -> List[float]:
if nodes is None:
nodes = self.g.nodes.values()
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,12 +68,11 @@ 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, dying;
bool deleted, push, dying;
u32 blockheight;

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

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

printf("%zu: %s%s%s%s", off,
printf("%zu: %s%s%s", off,
deleted ? "DELETED " : "",
push ? "PUSH " : "",
ratelimit ? "RATE-LIMITED " : "",
dying ? "DYING " : "");
if (print_timestamp)
printf("T=%u ", be32_to_cpu(hdr.timestamp));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ The flags currently defined are:
```
#define DELETED 0x8000
#define PUSH 0x4000
#define RATELIMIT 0x2000
#define DYING 0x0800
```
Expand All @@ -169,7 +169,7 @@ Deleted fields should be ignored: on restart, they will be removed as the gossip
The push flag indicates gossip which is generated locally: this is important for gossip timestamp filtering, where peers request gossip and we always send our own gossip messages even if the timestamp wasn't within their request.
The ratelimit flag indicates that this gossip message came too fast: we record it, but don't relay it to peers.
The dying flag indicates that this channel has been spent, but we keep it around for 12 blocks in case it's actually a splice.
Other flags should be ignored.
Expand Down Expand Up @@ -234,4 +234,4 @@ This is placed in the gossip_store file when a funding transaction is spent. `b
If you are keeping the file open to watch for changes:
- The file is append-only, so you can simply try reading more records using inotify (or equivalent) or simply checking every few seconds.
- If you see a `gossip_store_ended` message, reopen the file.
- If you see a `gossip_store_ended` message, reopen the file.
24 changes: 9 additions & 15 deletions gossipd/gossip_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,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 spam, bool dying, u64 *len)
bool dying, u64 *len)
{
struct gossip_hdr hdr;
u32 msglen;
Expand All @@ -74,8 +74,6 @@ static bool append_msg(int fd, const u8 *msg, u32 timestamp,
msglen = tal_count(msg);
hdr.len = cpu_to_be16(msglen);
hdr.flags = 0;
if (spam)
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_RATELIMIT_BIT);
if (dying)
hdr.flags |= CPU_TO_BE16(GOSSIP_STORE_DYING_BIT);
hdr.crc = cpu_to_be32(crc32c(timestamp, msg, msglen));
Expand All @@ -98,7 +96,7 @@ 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
* v14 removed zombie and spam flags
*/
static bool can_upgrade(u8 oldversion)
{
Expand Down Expand Up @@ -309,7 +307,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, &oldlen);
0, false, &oldlen);
close(old_fd);
status_debug("gossip_store_compact_offline: %zu deleted, %zu copied",
deleted, count);
Expand Down Expand Up @@ -368,19 +366,19 @@ struct gossip_store *gossip_store_new(struct daemon *daemon)

u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
u32 timestamp,
bool spam, bool dying, const u8 *addendum)
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, spam, dying, &gs->len)) {
if (!append_msg(gs->fd, gossip_msg, timestamp, 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, &gs->len)) {
if (addendum && !append_msg(gs->fd, addendum, 0, false, &gs->len)) {
status_broken("Failed writing addendum to gossip store: %s",
strerror(errno));
return 0;
Expand Down Expand Up @@ -514,7 +512,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, NULL);
0, false, NULL);
}

u32 gossip_store_get_timestamp(struct gossip_store *gs, u64 offset)
Expand Down Expand Up @@ -632,8 +630,6 @@ u32 gossip_store_load(struct gossip_store *gs)

gs->writable = false;
while (pread(gs->fd, &hdr, sizeof(hdr), gs->len) == sizeof(hdr)) {
bool spam;

msglen = be16_to_cpu(hdr.len);
checksum = be32_to_cpu(hdr.crc);
msg = tal_arr(tmpctx, u8, msglen);
Expand All @@ -654,7 +650,6 @@ u32 gossip_store_load(struct gossip_store *gs)
deleted++;
goto next;
}
spam = (be16_to_cpu(hdr.flags) & GOSSIP_STORE_RATELIMIT_BIT);

switch (fromwire_peektype(msg)) {
case WIRE_GOSSIP_STORE_CHANNEL_AMOUNT:
Expand Down Expand Up @@ -700,8 +695,7 @@ u32 gossip_store_load(struct gossip_store *gs)
case WIRE_CHANNEL_UPDATE:
if (!routing_add_channel_update(gs->daemon->rstate,
take(msg), gs->len,
NULL, false,
spam)) {
NULL, false)) {
bad = "Bad channel_update";
goto badmsg;
}
Expand All @@ -710,7 +704,7 @@ u32 gossip_store_load(struct gossip_store *gs)
case WIRE_NODE_ANNOUNCEMENT:
if (!routing_add_node_announcement(gs->daemon->rstate,
take(msg), gs->len,
NULL, NULL, spam)) {
NULL, NULL)) {
/* FIXME: This has been reported: routing.c
* has logged, so ignore. */
break;
Expand Down
3 changes: 1 addition & 2 deletions gossipd/gossip_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,12 @@ 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.
* @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 spam, bool dying,
u32 timestamp, bool dying,
const u8 *addendum);


Expand Down
Loading

0 comments on commit 07cd4a8

Please sign in to comment.