Skip to content

Commit 9c254c8

Browse files
rustyrussellcdecker
authored andcommitted
gossipd: when we refresh channel, don't override pending updates.
We can have an update pending because it's too fast, but refresh_local_channel is supposed to make sure we're up-to-date, so force immediate application in that case. Otherwise, we call update_local_channel at the bottom which frees the pending update. This can mean that we miss a change in fees, for example. Changelog-Fixed: errors: Errors returning a `channel_update` no longer return an outdated one. Signed-off-by: Rusty Russell <[email protected]>
1 parent 3018113 commit 9c254c8

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

gossipd/gossip_generation.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ struct local_cupdate {
314314

315315
bool disable;
316316
bool even_if_identical;
317+
bool even_if_too_soon;
317318

318319
u16 cltv_expiry_delta;
319320
struct amount_msat htlc_minimum, htlc_maximum;
@@ -409,7 +410,7 @@ static void update_local_channel(struct local_cupdate *lc /* frees! */)
409410
next = hc->bcast.timestamp
410411
+ GOSSIP_MIN_INTERVAL(daemon->rstate->dev_fast_gossip);
411412

412-
if (timestamp < next) {
413+
if (timestamp < next && !lc->even_if_too_soon) {
413414
status_debug("channel_update %s/%u: delaying %u secs",
414415
type_to_string(tmpctx,
415416
struct short_channel_id,
@@ -503,10 +504,21 @@ void refresh_local_channel(struct daemon *daemon,
503504
if (!is_halfchan_defined(hc))
504505
return;
505506

507+
/* If there's an update pending already, force it to apply now. */
508+
if (local_chan->channel_update_timer) {
509+
lc = reltimer_arg(local_chan->channel_update_timer);
510+
lc->even_if_too_soon = true;
511+
update_local_channel(lc);
512+
/* Free timer */
513+
local_chan->channel_update_timer
514+
= tal_free(local_chan->channel_update_timer);
515+
}
516+
506517
lc = tal(NULL, struct local_cupdate);
507518
lc->daemon = daemon;
508519
lc->local_chan = local_chan;
509520
lc->even_if_identical = even_if_identical;
521+
lc->even_if_too_soon = false;
510522

511523
prev = cast_const(u8 *,
512524
gossip_store_get(tmpctx, daemon->rstate->gs,
@@ -546,6 +558,7 @@ bool handle_local_channel_update(struct daemon *daemon,
546558

547559
lc->daemon = daemon;
548560
lc->even_if_identical = false;
561+
lc->even_if_too_soon = false;
549562

550563
/* FIXME: We should get scid from lightningd when setting up the
551564
* connection, so no per-peer daemon can mess with channels other than

gossipd/test/run-check_node_announcement.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
6868
/* Generated stub for queue_peer_msg */
6969
void queue_peer_msg(struct peer *peer UNNEEDED, const u8 *msg TAKES UNNEEDED)
7070
{ fprintf(stderr, "queue_peer_msg called!\n"); abort(); }
71+
/* Generated stub for reltimer_arg */
72+
void *reltimer_arg(struct oneshot *t UNNEEDED)
73+
{ fprintf(stderr, "reltimer_arg called!\n"); abort(); }
7174
/* Generated stub for status_failed */
7275
void status_failed(enum status_failreason code UNNEEDED,
7376
const char *fmt UNNEEDED, ...)

gossipd/test/run-crc32_of_update.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ void queue_peer_from_store(struct peer *peer UNNEEDED,
107107
/* Generated stub for queue_peer_msg */
108108
void queue_peer_msg(struct peer *peer UNNEEDED, const u8 *msg TAKES UNNEEDED)
109109
{ fprintf(stderr, "queue_peer_msg called!\n"); abort(); }
110+
/* Generated stub for reltimer_arg */
111+
void *reltimer_arg(struct oneshot *t UNNEEDED)
112+
{ fprintf(stderr, "reltimer_arg called!\n"); abort(); }
110113
/* Generated stub for status_failed */
111114
void status_failed(enum status_failreason code UNNEEDED,
112115
const char *fmt UNNEEDED, ...)

0 commit comments

Comments
 (0)