mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-01 17:47:30 +01:00
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>
This commit is contained in:
parent
178baeba6c
commit
70c4ac6d74
2 changed files with 34 additions and 8 deletions
|
@ -151,6 +151,9 @@ struct daemon {
|
||||||
|
|
||||||
/* Channels we've heard about, but don't know. */
|
/* Channels we've heard about, but don't know. */
|
||||||
struct short_channel_id *unknown_scids;
|
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? */
|
/*~ 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;
|
u8 *msg, *nannounce, *err;
|
||||||
struct node *self = get_node(daemon->rstate, &daemon->id);
|
struct node *self = get_node(daemon->rstate, &daemon->id);
|
||||||
|
|
||||||
/* BOLT #7:
|
/* Discard existing timer. */
|
||||||
*
|
daemon->node_announce_timer = tal_free(daemon->node_announce_timer);
|
||||||
* 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;
|
|
||||||
|
|
||||||
/* Make unsigned announcement. */
|
/* Make unsigned announcement. */
|
||||||
nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp);
|
nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp);
|
||||||
|
|
||||||
/* If it's the same as the previous, nothing to do. */
|
/* If it's the same as the previous, nothing to do. */
|
||||||
if (self && self->bcast.index) {
|
if (self && self->bcast.index) {
|
||||||
|
u32 next;
|
||||||
|
|
||||||
if (!nannounce_different(daemon->rstate->gs, self, nannounce))
|
if (!nannounce_different(daemon->rstate->gs, self, nannounce))
|
||||||
return;
|
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) */
|
/* Ask hsmd to sign it (synchronous) */
|
||||||
|
@ -3447,6 +3467,7 @@ int main(int argc, char *argv[])
|
||||||
list_head_init(&daemon->peers);
|
list_head_init(&daemon->peers);
|
||||||
daemon->unknown_scids = tal_arr(daemon, struct short_channel_id, 0);
|
daemon->unknown_scids = tal_arr(daemon, struct short_channel_id, 0);
|
||||||
daemon->gossip_missing = NULL;
|
daemon->gossip_missing = NULL;
|
||||||
|
daemon->node_announce_timer = NULL;
|
||||||
|
|
||||||
/* Note the use of time_mono() here. That's a monotonic clock, which
|
/* 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
|
* is really useful: it can only be used to measure relative events
|
||||||
|
|
|
@ -967,6 +967,8 @@ def test_node_reannounce(node_factory, bitcoind):
|
||||||
|
|
||||||
l1.stop()
|
l1.stop()
|
||||||
l1.daemon.opts['alias'] = 'SENIORBEAM'
|
l1.daemon.opts['alias'] = 'SENIORBEAM'
|
||||||
|
# It won't update within 5 seconds, so sleep.
|
||||||
|
time.sleep(5)
|
||||||
l1.start()
|
l1.start()
|
||||||
|
|
||||||
# Wait for l1 to send us its own node_announcement.
|
# 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!)
|
# l1 should retransmit it exactly the same (no timestamp change!)
|
||||||
l2.daemon.wait_for_log(r'{}.*\[IN\] {}'.format(l1.info['id'], nannouncement))
|
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):
|
def test_gossipwith(node_factory):
|
||||||
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
|
l1, l2 = node_factory.line_graph(2, wait_for_announce=True)
|
||||||
|
|
Loading…
Add table
Reference in a new issue