Browse Source

gossipd: suppress our own too-close node_announcement messages.

Never make them less than gossip_min_interval apart.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
travis-debug
Rusty Russell 5 years ago
parent
commit
70c4ac6d74
  1. 37
      gossipd/gossipd.c
  2. 5
      tests/test_gossip.py

37
gossipd/gossipd.c

@ -151,6 +151,9 @@ struct daemon {
/* Channels we've heard about, but don't know. */
struct short_channel_id *unknown_scids;
/* Timer until we can send a new node_announcement */
struct oneshot *node_announce_timer;
};
/*~ How gossipy do we ask a peer to be? */
@ -569,22 +572,39 @@ static void update_own_node_announcement(struct daemon *daemon)
u8 *msg, *nannounce, *err;
struct node *self = get_node(daemon->rstate, &daemon->id);
/* BOLT #7:
*
* The origin node:
* - MUST set `timestamp` to be greater than that of any previous
* `node_announcement` it has previously created.
*/
if (self && self->bcast.index && timestamp <= self->bcast.timestamp)
timestamp = self->bcast.timestamp + 1;
/* Discard existing timer. */
daemon->node_announce_timer = tal_free(daemon->node_announce_timer);
/* Make unsigned announcement. */
nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp);
/* If it's the same as the previous, nothing to do. */
if (self && self->bcast.index) {
u32 next;
if (!nannounce_different(daemon->rstate->gs, self, nannounce))
return;
/* BOLT #7:
*
* The origin node:
* - MUST set `timestamp` to be greater than that of any
* previous `node_announcement` it has previously created.
*/
/* We do better: never send them within more than 5 minutes. */
next = self->bcast.timestamp + daemon->gossip_min_interval;
if (timestamp < next) {
status_debug("node_announcement: delaying %u secs",
next - timestamp);
daemon->node_announce_timer
= new_reltimer(&daemon->timers,
daemon,
time_from_sec(next - timestamp),
update_own_node_announcement,
daemon);
return;
}
}
/* Ask hsmd to sign it (synchronous) */
@ -3447,6 +3467,7 @@ int main(int argc, char *argv[])
list_head_init(&daemon->peers);
daemon->unknown_scids = tal_arr(daemon, struct short_channel_id, 0);
daemon->gossip_missing = NULL;
daemon->node_announce_timer = NULL;
/* Note the use of time_mono() here. That's a monotonic clock, which
* is really useful: it can only be used to measure relative events

5
tests/test_gossip.py

@ -967,6 +967,8 @@ def test_node_reannounce(node_factory, bitcoind):
l1.stop()
l1.daemon.opts['alias'] = 'SENIORBEAM'
# It won't update within 5 seconds, so sleep.
time.sleep(5)
l1.start()
# Wait for l1 to send us its own node_announcement.
@ -984,6 +986,9 @@ def test_node_reannounce(node_factory, bitcoind):
# l1 should retransmit it exactly the same (no timestamp change!)
l2.daemon.wait_for_log(r'{}.*\[IN\] {}'.format(l1.info['id'], nannouncement))
# Won't have queued up another one, either.
assert not l1.daemon.is_in_log('node_announcement: delaying')
def test_gossipwith(node_factory):
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)

Loading…
Cancel
Save