Browse Source

ratelimit: adjust based on --dev-fast-gossip, test.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
39c9dcbafc
  1. 4
      gossipd/gossip_constants.h
  2. 12
      gossipd/routing.c
  3. 50
      tests/test_gossip.py

4
gossipd/gossip_constants.h

@ -77,4 +77,8 @@
#define GOSSIP_BEFORE_DEADLINE(dev_fast_gossip_flag) \
DEV_FAST_GOSSIP(dev_fast_gossip_flag, 30, 24*60*60)
/* How many seconds per token? Normally 1 hour. */
#define GOSSIP_TOKEN_TIME(dev_fast_gossip_flag) \
DEV_FAST_GOSSIP(dev_fast_gossip_flag, 1, 3600)
#endif /* LIGHTNING_GOSSIPD_GOSSIP_CONSTANTS_H */

12
gossipd/routing.c

@ -41,14 +41,16 @@ struct pending_node_announce {
#define TOKENS_PER_MSG 24
#define TOKEN_MAX (24 * 4)
static bool ratelimit(u8 *tokens, u32 prev_timestamp, u32 new_timestamp)
static bool ratelimit(const struct routing_state *rstate,
u8 *tokens, u32 prev_timestamp, u32 new_timestamp)
{
u64 num_tokens;
assert(new_timestamp >= prev_timestamp);
/* First, top up tokens, avoiding overflow. */
num_tokens = *tokens + (new_timestamp - prev_timestamp) / 3600;
num_tokens = *tokens + ((new_timestamp - prev_timestamp)
/ GOSSIP_TOKEN_TIME(rstate->dev_fast_gossip));
if (num_tokens > TOKEN_MAX)
num_tokens = TOKEN_MAX;
*tokens = num_tokens;
@ -2013,7 +2015,8 @@ bool routing_add_channel_update(struct routing_state *rstate,
}
/* Make sure it's not spamming us. */
if (!ratelimit(&hc->tokens, hc->bcast.timestamp, timestamp)) {
if (!ratelimit(rstate,
&hc->tokens, hc->bcast.timestamp, timestamp)) {
status_debug("Ignoring spammy update for %s/%u"
" (last %u, now %u)",
type_to_string(tmpctx,
@ -2364,7 +2367,8 @@ bool routing_add_node_announcement(struct routing_state *rstate,
}
/* Make sure it's not spamming us. */
if (!ratelimit(&node->tokens, node->bcast.timestamp, timestamp)) {
if (!ratelimit(rstate,
&node->tokens, node->bcast.timestamp, timestamp)) {
status_debug("Ignoring spammy nannounce for %s"
" (last %u, now %u)",
type_to_string(tmpctx,

50
tests/test_gossip.py

@ -1376,7 +1376,7 @@ def test_gossip_store_compact_on_load(node_factory, bitcoind):
l2.restart()
wait_for(lambda: l2.daemon.is_in_log('gossip_store_compact_offline: [5-8] deleted, 9 copied'))
wait_for(lambda: l2.daemon.is_in_log(r'gossip_store_compact_offline: [5-8] deleted, 9 copied'))
wait_for(lambda: l2.daemon.is_in_log(r'gossip_store: Read 1/4/2/0 cannounce/cupdate/nannounce/cdelete from store \(0 deleted\) in 1446 bytes'))
@ -1454,3 +1454,51 @@ def test_gossip_no_backtalk(node_factory):
# With DEVELOPER, this is long enough for gossip flush.
time.sleep(2)
assert not l3.daemon.is_in_log(r'\[OUT\] 0100')
@unittest.skipIf(not DEVELOPER, "Needs --dev-gossip")
def test_gossip_ratelimit(node_factory):
# These make the channel exist, but we use our own gossip.
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
# Here are some ones I generated earlier (by removing gossip
# ratelimiting)
l3 = node_factory.get_node(options={'dev-gossip-time': 1568096251})
subprocess.run(['devtools/gossipwith',
'--max-messages=0',
'{}@localhost:{}'.format(l3.info['id'], l3.port),
# announcement
'0100987b271fc95a37dbed78e6159e0ab792cda64603780454ce80832b4e31f63a6760abc8fdc53be35bb7cfccd125ee3d15b4fbdfb42165098970c19c7822bb413f46390e0c043c777226927eacd2186a03f064e4bdc30f891cb6e4990af49967d34b338755e99d728987e3d49227815e17f3ab40092434a59e33548e870071176db7d44d8c8f4c4cac27ae6554eb9350e97d47617e3a1355296c78e8234446fa2f138ad1b03439f18520227fb9e9eb92689b3a0ed36e6764f5a41777e9a2a4ce1026d19a4e4d8f7715c13ac2d6bf3238608a1ccf9afd91f774d84d170d9edddebf7460c54d49bd6cd81410bc3eeeba2b7278b1b5f7e748d77d793f31086847d582000006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f0000670000010001022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d590266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c0351802e3bd38009866c9da8ec4aa99cc4ea9c6c0dd46df15c61ef0ce1f271291714e5702324266de8403b3ab157a09f1f784d587af61831c998c151bcc21bb74c2b2314b',
# first update is free
'010225bfd9c5e2c5660188a14deb4002cd645ee67f00ad3b82146e46711ec460cb0c6819fdd1c680cb6d24e3906679ef071f13243a04a123e4b83310ebf0518ffd4206226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00006700000100015d773ffb010100060000000000000000000000010000000a000000003b023380'],
check=True, timeout=TIMEOUT)
# Wait for it to process channel.
wait_for(lambda: [c['fee_per_millionth'] for c in l3.rpc.listchannels()['channels']] == [10])
subprocess.run(['devtools/gossipwith',
'--max-messages=0',
'{}@localhost:{}'.format(l3.info['id'], l3.port),
# next 4 are let through...
'01023a892ad9c9953a54ad3b8e2e03a93d1c973241b62f9a5cd1f17d5cdf08de0e8b4fcd24aa8bd45a48b788fe9dab3d416f28dfa390bc900ec0176ec5bd1afd435706226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00006700000100015d77400001010006000000000000000000000014000003e9000000003b023380',
'010245966763623ebc16796165263d4b21711ef04ebf3929491e695ff89ed2b8ccc0668ceb9e35e0ff5b8901d95732a119c1ed84ac99861daa2de462118f7b70049f06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00006700000100015d77400101010006000000000000000000000014000003ea000000003b023380',
'0102c479b7684b9db496b844f6925f4ffd8a27c5840a020d1b537623c1545dcd8e195776381bbf51213e541a853a4a49a0faf84316e7ccca5e7074901a96bbabe04e06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00006700000100015d77400201010006000000000000000000000014000003eb000000003b023380',
# timestamp=1568096259, fee_proportional_millionths=1004
'01024b866012d995d3d7aec7b7218a283de2d03492dbfa21e71dd546ec2e36c3d4200453420aa02f476f99c73fe1e223ea192f5fa544b70a8319f2a216f1513d503d06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00006700000100015d77400301010006000000000000000000000014000003ec000000003b023380',
# update 5 marks you as a nasty spammer!
'01025b5b5a0daed874ab02bd3356d38190ff46bbaf5f10db5067da70f3ca203480ca78059e6621c6143f3da4e454d0adda6d01a9980ed48e71ccd0c613af73570a7106226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00006700000100015d77400401010006000000000000000000000014000003ed000000003b023380'],
check=True, timeout=TIMEOUT)
wait_for(lambda: [c['fee_per_millionth'] for c in l3.rpc.listchannels()['channels']] == [1004])
# 24 seconds later, it will accept another.
l3.rpc.call('dev-gossip-set-time', [1568096251 + 24])
subprocess.run(['devtools/gossipwith',
'--max-messages=0',
'{}@localhost:{}'.format(l3.info['id'], l3.port),
# update 6: timestamp=1568096284 fee_proportional_millionths=1006
'010282d24bcd984956bd9b891848404ee59d89643923b21641d2c2c0770a51b8f5da00cef82458add970f0b654aa4c8d54f68a9a1cc6470a35810303b09437f1f73d06226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f00006700000100015d77401c01010006000000000000000000000014000003ee000000003b023380'],
check=True, timeout=TIMEOUT)
wait_for(lambda: [c['fee_per_millionth'] for c in l3.rpc.listchannels()['channels']] == [1006])

Loading…
Cancel
Save