gossipd: update node announcement even if we change within a second.

Usually Travis triggers corner cases because it's so slow, but this
time the moons aligned, and it managed to fail test_node_reannounce
because it generated the updated node_announcement with the same
timestamp as the old one.

This is because we only updated "last_announce_timestamp" when
we generated the announcement, not when we got it off the wire or
loaded it from the gossip store.

The fix is to ask the routing code what the latest timestamp is;
we could still generate a clashing timestamp if (1) the gossip store
is lost, and (2) we restart within one second.  Hard to care.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-10-16 14:14:53 +10:30
parent 66ca2a333f
commit bbc36a7bec

View File

@ -90,9 +90,6 @@ struct daemon {
/* What we can actually announce. */ /* What we can actually announce. */
struct wireaddr *announcable; struct wireaddr *announcable;
/* To make sure our node_announcement timestamps increase */
u32 last_announce_timestamp;
}; };
struct peer { struct peer {
@ -313,11 +310,17 @@ static void send_node_announcement(struct daemon *daemon)
u32 timestamp = time_now().ts.tv_sec; u32 timestamp = time_now().ts.tv_sec;
secp256k1_ecdsa_signature sig; secp256k1_ecdsa_signature sig;
u8 *msg, *nannounce, *err; u8 *msg, *nannounce, *err;
s64 last_timestamp;
struct node *self = get_node(daemon->rstate, &daemon->id);
if (self)
last_timestamp = self->last_timestamp;
else
last_timestamp = -1;
/* Timestamps must move forward, or announce will be ignored! */ /* Timestamps must move forward, or announce will be ignored! */
if (timestamp <= daemon->last_announce_timestamp) if (timestamp <= last_timestamp)
timestamp = daemon->last_announce_timestamp + 1; timestamp = last_timestamp + 1;
daemon->last_announce_timestamp = timestamp;
nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp); nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp);
@ -2149,7 +2152,6 @@ int main(int argc, char *argv[])
daemon = tal(NULL, struct daemon); daemon = tal(NULL, struct daemon);
list_head_init(&daemon->peers); list_head_init(&daemon->peers);
timers_init(&daemon->timers, time_mono()); timers_init(&daemon->timers, time_mono());
daemon->last_announce_timestamp = 0;
/* stdin == control */ /* stdin == control */
daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req, daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req,