mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 15:44:21 +01:00
gossipd: make use of new ratelimit bit in gossip_store length mask
routing.c now flags rate-limited gossip as it enters the gossip_store but makes use of it in updating the routing graph. Flagged gossip is not rebroadcast to gossip peers. Changelog-Changed: gossipd: now accepts spam gossip, but squelches it for peers.
This commit is contained in:
committed by
Rusty Russell
parent
cbafc0fa33
commit
9dc794dba8
@@ -12,8 +12,10 @@ import struct
|
|||||||
GOSSIP_STORE_VERSIONS = [0x09, 0x0a]
|
GOSSIP_STORE_VERSIONS = [0x09, 0x0a]
|
||||||
GOSSIP_STORE_LEN_DELETED_BIT = 0x80000000
|
GOSSIP_STORE_LEN_DELETED_BIT = 0x80000000
|
||||||
GOSSIP_STORE_LEN_PUSH_BIT = 0x40000000
|
GOSSIP_STORE_LEN_PUSH_BIT = 0x40000000
|
||||||
|
GOSSIP_STORE_LEN_RATELIMIT_BIT = 0x20000000
|
||||||
GOSSIP_STORE_LEN_MASK = (~(GOSSIP_STORE_LEN_PUSH_BIT
|
GOSSIP_STORE_LEN_MASK = (~(GOSSIP_STORE_LEN_PUSH_BIT
|
||||||
| GOSSIP_STORE_LEN_DELETED_BIT))
|
| GOSSIP_STORE_LEN_DELETED_BIT
|
||||||
|
| GOSSIP_STORE_LEN_RATELIMIT_BIT))
|
||||||
|
|
||||||
# These duplicate constants in lightning/gossipd/gossip_store_wiregen.h
|
# These duplicate constants in lightning/gossipd/gossip_store_wiregen.h
|
||||||
WIRE_GOSSIP_STORE_PRIVATE_CHANNEL = 4104
|
WIRE_GOSSIP_STORE_PRIVATE_CHANNEL = 4104
|
||||||
|
|||||||
@@ -52,10 +52,11 @@ int main(int argc, char *argv[])
|
|||||||
struct short_channel_id scid;
|
struct short_channel_id scid;
|
||||||
u32 msglen = be32_to_cpu(hdr.len);
|
u32 msglen = be32_to_cpu(hdr.len);
|
||||||
u8 *msg, *inner;
|
u8 *msg, *inner;
|
||||||
bool deleted, push;
|
bool deleted, push, ratelimit;
|
||||||
|
|
||||||
deleted = (msglen & GOSSIP_STORE_LEN_DELETED_BIT);
|
deleted = (msglen & GOSSIP_STORE_LEN_DELETED_BIT);
|
||||||
push = (msglen & GOSSIP_STORE_LEN_PUSH_BIT);
|
push = (msglen & GOSSIP_STORE_LEN_PUSH_BIT);
|
||||||
|
ratelimit = (msglen & GOSSIP_STORE_LEN_RATELIMIT_BIT);
|
||||||
|
|
||||||
msglen &= GOSSIP_STORE_LEN_MASK;
|
msglen &= GOSSIP_STORE_LEN_MASK;
|
||||||
msg = tal_arr(NULL, u8, msglen);
|
msg = tal_arr(NULL, u8, msglen);
|
||||||
@@ -66,9 +67,10 @@ int main(int argc, char *argv[])
|
|||||||
!= crc32c(be32_to_cpu(hdr.timestamp), msg, msglen))
|
!= crc32c(be32_to_cpu(hdr.timestamp), msg, msglen))
|
||||||
warnx("Checksum verification failed");
|
warnx("Checksum verification failed");
|
||||||
|
|
||||||
printf("%zu: %s%s", off,
|
printf("%zu: %s%s%s", off,
|
||||||
deleted ? "DELETED " : "",
|
deleted ? "DELETED " : "",
|
||||||
push ? "PUSH " : "");
|
push ? "PUSH " : "",
|
||||||
|
ratelimit ? "RATE-LIMITED " : "");
|
||||||
if (deleted && !print_deleted) {
|
if (deleted && !print_deleted) {
|
||||||
printf("\n");
|
printf("\n");
|
||||||
goto end;
|
goto end;
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ static ssize_t gossip_pwritev(int fd, const struct iovec *iov, int iovcnt,
|
|||||||
#endif /* !HAVE_PWRITEV */
|
#endif /* !HAVE_PWRITEV */
|
||||||
|
|
||||||
static bool append_msg(int fd, const u8 *msg, u32 timestamp,
|
static bool append_msg(int fd, const u8 *msg, u32 timestamp,
|
||||||
bool push, u64 *len)
|
bool push, bool spam, u64 *len)
|
||||||
{
|
{
|
||||||
struct gossip_hdr hdr;
|
struct gossip_hdr hdr;
|
||||||
u32 msglen;
|
u32 msglen;
|
||||||
@@ -84,6 +84,8 @@ static bool append_msg(int fd, const u8 *msg, u32 timestamp,
|
|||||||
hdr.len = cpu_to_be32(msglen);
|
hdr.len = cpu_to_be32(msglen);
|
||||||
if (push)
|
if (push)
|
||||||
hdr.len |= CPU_TO_BE32(GOSSIP_STORE_LEN_PUSH_BIT);
|
hdr.len |= CPU_TO_BE32(GOSSIP_STORE_LEN_PUSH_BIT);
|
||||||
|
if (spam)
|
||||||
|
hdr.len |= CPU_TO_BE32(GOSSIP_STORE_LEN_RATELIMIT_BIT);
|
||||||
hdr.crc = cpu_to_be32(crc32c(timestamp, msg, msglen));
|
hdr.crc = cpu_to_be32(crc32c(timestamp, msg, msglen));
|
||||||
hdr.timestamp = cpu_to_be32(timestamp);
|
hdr.timestamp = cpu_to_be32(timestamp);
|
||||||
|
|
||||||
@@ -277,7 +279,7 @@ static u32 gossip_store_compact_offline(struct routing_state *rstate)
|
|||||||
oldlen = lseek(old_fd, SEEK_END, 0);
|
oldlen = lseek(old_fd, SEEK_END, 0);
|
||||||
newlen = lseek(new_fd, SEEK_END, 0);
|
newlen = lseek(new_fd, SEEK_END, 0);
|
||||||
append_msg(old_fd, towire_gossip_store_ended(tmpctx, newlen),
|
append_msg(old_fd, towire_gossip_store_ended(tmpctx, newlen),
|
||||||
0, true, &oldlen);
|
0, true, false, &oldlen);
|
||||||
close(old_fd);
|
close(old_fd);
|
||||||
status_debug("gossip_store_compact_offline: %zu deleted, %zu copied",
|
status_debug("gossip_store_compact_offline: %zu deleted, %zu copied",
|
||||||
deleted, count);
|
deleted, count);
|
||||||
@@ -565,7 +567,7 @@ bool gossip_store_compact(struct gossip_store *gs)
|
|||||||
|
|
||||||
/* Write end marker now new one is ready */
|
/* Write end marker now new one is ready */
|
||||||
append_msg(gs->fd, towire_gossip_store_ended(tmpctx, len),
|
append_msg(gs->fd, towire_gossip_store_ended(tmpctx, len),
|
||||||
0, true, &gs->len);
|
0, true, false, &gs->len);
|
||||||
|
|
||||||
gs->count = count;
|
gs->count = count;
|
||||||
gs->deleted = 0;
|
gs->deleted = 0;
|
||||||
@@ -586,19 +588,19 @@ disable:
|
|||||||
|
|
||||||
u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
|
u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
|
||||||
u32 timestamp, bool push,
|
u32 timestamp, bool push,
|
||||||
const u8 *addendum)
|
bool spam, const u8 *addendum)
|
||||||
{
|
{
|
||||||
u64 off = gs->len;
|
u64 off = gs->len;
|
||||||
|
|
||||||
/* Should never get here during loading! */
|
/* Should never get here during loading! */
|
||||||
assert(gs->writable);
|
assert(gs->writable);
|
||||||
|
|
||||||
if (!append_msg(gs->fd, gossip_msg, timestamp, push, &gs->len)) {
|
if (!append_msg(gs->fd, gossip_msg, timestamp, push, spam, &gs->len)) {
|
||||||
status_broken("Failed writing to gossip store: %s",
|
status_broken("Failed writing to gossip store: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (addendum && !append_msg(gs->fd, addendum, 0, false, &gs->len)) {
|
if (addendum && !append_msg(gs->fd, addendum, 0, false, false, &gs->len)) {
|
||||||
status_broken("Failed writing addendum to gossip store: %s",
|
status_broken("Failed writing addendum to gossip store: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
return 0;
|
return 0;
|
||||||
@@ -615,7 +617,7 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update)
|
|||||||
/* A local update for an unannounced channel: not broadcastable, but
|
/* A local update for an unannounced channel: not broadcastable, but
|
||||||
* otherwise the same as a normal channel_update */
|
* otherwise the same as a normal channel_update */
|
||||||
const u8 *pupdate = towire_gossip_store_private_update(tmpctx, update);
|
const u8 *pupdate = towire_gossip_store_private_update(tmpctx, update);
|
||||||
return gossip_store_add(gs, pupdate, 0, false, NULL);
|
return gossip_store_add(gs, pupdate, 0, false, false, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns index of following entry. */
|
/* Returns index of following entry. */
|
||||||
@@ -675,7 +677,7 @@ void gossip_store_mark_channel_deleted(struct gossip_store *gs,
|
|||||||
const struct short_channel_id *scid)
|
const struct short_channel_id *scid)
|
||||||
{
|
{
|
||||||
gossip_store_add(gs, towire_gossip_store_delete_chan(tmpctx, scid),
|
gossip_store_add(gs, towire_gossip_store_delete_chan(tmpctx, scid),
|
||||||
0, false, NULL);
|
0, false, false, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
const u8 *gossip_store_get(const tal_t *ctx,
|
const u8 *gossip_store_get(const tal_t *ctx,
|
||||||
|
|||||||
@@ -40,11 +40,12 @@ u64 gossip_store_add_private_update(struct gossip_store *gs, const u8 *update);
|
|||||||
* @gossip_msg: the gossip message to insert.
|
* @gossip_msg: the gossip message to insert.
|
||||||
* @timestamp: the timestamp for filtering of this messsage.
|
* @timestamp: the timestamp for filtering of this messsage.
|
||||||
* @push: true if this should be sent to peers despite any timestamp filters.
|
* @push: true if this should be sent to peers despite any timestamp filters.
|
||||||
|
* @spam: true if this message is rate-limited and squelched to peers.
|
||||||
* @addendum: another message to append immediately after this
|
* @addendum: another message to append immediately after this
|
||||||
* (for appending amounts to channel_announcements for internal use).
|
* (for appending amounts to channel_announcements for internal use).
|
||||||
*/
|
*/
|
||||||
u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
|
u64 gossip_store_add(struct gossip_store *gs, const u8 *gossip_msg,
|
||||||
u32 timestamp, bool push, const u8 *addendum);
|
u32 timestamp, bool push, bool spam, const u8 *addendum);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -437,6 +437,7 @@ static void force_node_announce_rexmit(struct routing_state *rstate,
|
|||||||
announce,
|
announce,
|
||||||
node->bcast.timestamp,
|
node->bcast.timestamp,
|
||||||
is_local,
|
is_local,
|
||||||
|
false,
|
||||||
NULL);
|
NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -790,6 +791,7 @@ static void add_channel_announce_to_broadcast(struct routing_state *rstate,
|
|||||||
channel_announce,
|
channel_announce,
|
||||||
chan->bcast.timestamp,
|
chan->bcast.timestamp,
|
||||||
is_local,
|
is_local,
|
||||||
|
false,
|
||||||
addendum);
|
addendum);
|
||||||
rstate->local_channel_announced |= is_local;
|
rstate->local_channel_announced |= is_local;
|
||||||
}
|
}
|
||||||
@@ -1255,6 +1257,7 @@ bool routing_add_channel_update(struct routing_state *rstate,
|
|||||||
struct unupdated_channel *uc;
|
struct unupdated_channel *uc;
|
||||||
u8 direction;
|
u8 direction;
|
||||||
struct amount_sat sat;
|
struct amount_sat sat;
|
||||||
|
bool spam;
|
||||||
|
|
||||||
/* Make sure we own msg, even if we don't save it. */
|
/* Make sure we own msg, even if we don't save it. */
|
||||||
if (taken(update))
|
if (taken(update))
|
||||||
@@ -1360,16 +1363,19 @@ bool routing_add_channel_update(struct routing_state *rstate,
|
|||||||
if (!ratelimit(rstate,
|
if (!ratelimit(rstate,
|
||||||
&hc->tokens, hc->bcast.timestamp, timestamp)) {
|
&hc->tokens, hc->bcast.timestamp, timestamp)) {
|
||||||
status_peer_debug(peer ? &peer->id : NULL,
|
status_peer_debug(peer ? &peer->id : NULL,
|
||||||
"Ignoring spammy update for %s/%u"
|
"Spammy update for %s/%u flagged"
|
||||||
" (last %u, now %u)",
|
" (last %u, now %u)",
|
||||||
type_to_string(tmpctx,
|
type_to_string(tmpctx,
|
||||||
struct short_channel_id,
|
struct short_channel_id,
|
||||||
&short_channel_id),
|
&short_channel_id),
|
||||||
direction,
|
direction,
|
||||||
hc->bcast.timestamp, timestamp);
|
hc->bcast.timestamp, timestamp);
|
||||||
/* Ignoring != failing */
|
spam = true;
|
||||||
return true;
|
} else {
|
||||||
|
spam = false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
spam = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
chan->half[direction].bcast.timestamp = timestamp;
|
chan->half[direction].bcast.timestamp = timestamp;
|
||||||
@@ -1414,7 +1420,7 @@ bool routing_add_channel_update(struct routing_state *rstate,
|
|||||||
= gossip_store_add(rstate->gs, update,
|
= gossip_store_add(rstate->gs, update,
|
||||||
hc->bcast.timestamp,
|
hc->bcast.timestamp,
|
||||||
local_direction(rstate, chan, NULL),
|
local_direction(rstate, chan, NULL),
|
||||||
NULL);
|
spam, NULL);
|
||||||
if (hc->bcast.timestamp > rstate->last_timestamp
|
if (hc->bcast.timestamp > rstate->last_timestamp
|
||||||
&& hc->bcast.timestamp < time_now().ts.tv_sec)
|
&& hc->bcast.timestamp < time_now().ts.tv_sec)
|
||||||
rstate->last_timestamp = hc->bcast.timestamp;
|
rstate->last_timestamp = hc->bcast.timestamp;
|
||||||
@@ -1581,6 +1587,7 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
|||||||
u8 alias[32];
|
u8 alias[32];
|
||||||
u8 *features, *addresses;
|
u8 *features, *addresses;
|
||||||
struct tlv_node_ann_tlvs *na_tlv;
|
struct tlv_node_ann_tlvs *na_tlv;
|
||||||
|
bool spam;
|
||||||
|
|
||||||
if (was_unknown)
|
if (was_unknown)
|
||||||
*was_unknown = false;
|
*was_unknown = false;
|
||||||
@@ -1670,15 +1677,18 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
|||||||
if (!ratelimit(rstate,
|
if (!ratelimit(rstate,
|
||||||
&node->tokens, node->bcast.timestamp, timestamp)) {
|
&node->tokens, node->bcast.timestamp, timestamp)) {
|
||||||
status_peer_debug(peer ? &peer->id : NULL,
|
status_peer_debug(peer ? &peer->id : NULL,
|
||||||
"Ignoring spammy nannounce for %s"
|
"Spammy nannounce for %s flagged"
|
||||||
" (last %u, now %u)",
|
" (last %u, now %u)",
|
||||||
type_to_string(tmpctx,
|
type_to_string(tmpctx,
|
||||||
struct node_id,
|
struct node_id,
|
||||||
&node_id),
|
&node_id),
|
||||||
node->bcast.timestamp, timestamp);
|
node->bcast.timestamp, timestamp);
|
||||||
/* Ignoring != failing */
|
spam = true;
|
||||||
return true;
|
} else {
|
||||||
|
spam = false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
spam = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Harmless if it was never added */
|
/* Harmless if it was never added */
|
||||||
@@ -1699,6 +1709,7 @@ bool routing_add_node_announcement(struct routing_state *rstate,
|
|||||||
node->bcast.timestamp,
|
node->bcast.timestamp,
|
||||||
node_id_eq(&node_id,
|
node_id_eq(&node_id,
|
||||||
&rstate->local_id),
|
&rstate->local_id),
|
||||||
|
spam,
|
||||||
NULL);
|
NULL);
|
||||||
peer_supplied_good_gossip(peer, 1);
|
peer_supplied_good_gossip(peer, 1);
|
||||||
}
|
}
|
||||||
@@ -1919,7 +1930,7 @@ bool routing_add_private_channel(struct routing_state *rstate,
|
|||||||
u8 *msg = towire_gossip_store_private_channel(tmpctx,
|
u8 *msg = towire_gossip_store_private_channel(tmpctx,
|
||||||
capacity,
|
capacity,
|
||||||
chan_ann);
|
chan_ann);
|
||||||
index = gossip_store_add(rstate->gs, msg, 0, false, NULL);
|
index = gossip_store_add(rstate->gs, msg, 0, false, false, NULL);
|
||||||
}
|
}
|
||||||
chan->bcast.index = index;
|
chan->bcast.index = index;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
|||||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||||
/* Generated stub for gossip_store_add */
|
/* Generated stub for gossip_store_add */
|
||||||
u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED,
|
u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED,
|
||||||
u32 timestamp UNNEEDED, bool push UNNEEDED, const u8 *addendum UNNEEDED)
|
u32 timestamp UNNEEDED, bool push UNNEEDED, bool spam UNNEEDED, const u8 *addendum UNNEEDED)
|
||||||
{ fprintf(stderr, "gossip_store_add called!\n"); abort(); }
|
{ fprintf(stderr, "gossip_store_add called!\n"); abort(); }
|
||||||
/* Generated stub for gossip_store_add_private_update */
|
/* Generated stub for gossip_store_add_private_update */
|
||||||
u64 gossip_store_add_private_update(struct gossip_store *gs UNNEEDED, const u8 *update UNNEEDED)
|
u64 gossip_store_add_private_update(struct gossip_store *gs UNNEEDED, const u8 *update UNNEEDED)
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ void ecdh(const struct pubkey *point UNNEEDED, struct secret *ss UNNEEDED)
|
|||||||
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
{ fprintf(stderr, "ecdh called!\n"); abort(); }
|
||||||
/* Generated stub for gossip_store_add */
|
/* Generated stub for gossip_store_add */
|
||||||
u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED,
|
u64 gossip_store_add(struct gossip_store *gs UNNEEDED, const u8 *gossip_msg UNNEEDED,
|
||||||
u32 timestamp UNNEEDED, bool push UNNEEDED, const u8 *addendum UNNEEDED)
|
u32 timestamp UNNEEDED, bool push UNNEEDED, bool spam UNNEEDED, const u8 *addendum UNNEEDED)
|
||||||
{ fprintf(stderr, "gossip_store_add called!\n"); abort(); }
|
{ fprintf(stderr, "gossip_store_add called!\n"); abort(); }
|
||||||
/* Generated stub for gossip_store_add_private_update */
|
/* Generated stub for gossip_store_add_private_update */
|
||||||
u64 gossip_store_add_private_update(struct gossip_store *gs UNNEEDED, const u8 *update UNNEEDED)
|
u64 gossip_store_add_private_update(struct gossip_store *gs UNNEEDED, const u8 *update UNNEEDED)
|
||||||
|
|||||||
Reference in New Issue
Block a user