mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 18:57:06 +01:00
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 <rusty@rustcorp.com.au>
This commit is contained in:
parent
3018113012
commit
9c254c8387
3 changed files with 20 additions and 1 deletions
|
@ -314,6 +314,7 @@ struct local_cupdate {
|
||||||
|
|
||||||
bool disable;
|
bool disable;
|
||||||
bool even_if_identical;
|
bool even_if_identical;
|
||||||
|
bool even_if_too_soon;
|
||||||
|
|
||||||
u16 cltv_expiry_delta;
|
u16 cltv_expiry_delta;
|
||||||
struct amount_msat htlc_minimum, htlc_maximum;
|
struct amount_msat htlc_minimum, htlc_maximum;
|
||||||
|
@ -409,7 +410,7 @@ static void update_local_channel(struct local_cupdate *lc /* frees! */)
|
||||||
next = hc->bcast.timestamp
|
next = hc->bcast.timestamp
|
||||||
+ GOSSIP_MIN_INTERVAL(daemon->rstate->dev_fast_gossip);
|
+ GOSSIP_MIN_INTERVAL(daemon->rstate->dev_fast_gossip);
|
||||||
|
|
||||||
if (timestamp < next) {
|
if (timestamp < next && !lc->even_if_too_soon) {
|
||||||
status_debug("channel_update %s/%u: delaying %u secs",
|
status_debug("channel_update %s/%u: delaying %u secs",
|
||||||
type_to_string(tmpctx,
|
type_to_string(tmpctx,
|
||||||
struct short_channel_id,
|
struct short_channel_id,
|
||||||
|
@ -503,10 +504,21 @@ void refresh_local_channel(struct daemon *daemon,
|
||||||
if (!is_halfchan_defined(hc))
|
if (!is_halfchan_defined(hc))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
/* If there's an update pending already, force it to apply now. */
|
||||||
|
if (local_chan->channel_update_timer) {
|
||||||
|
lc = reltimer_arg(local_chan->channel_update_timer);
|
||||||
|
lc->even_if_too_soon = true;
|
||||||
|
update_local_channel(lc);
|
||||||
|
/* Free timer */
|
||||||
|
local_chan->channel_update_timer
|
||||||
|
= tal_free(local_chan->channel_update_timer);
|
||||||
|
}
|
||||||
|
|
||||||
lc = tal(NULL, struct local_cupdate);
|
lc = tal(NULL, struct local_cupdate);
|
||||||
lc->daemon = daemon;
|
lc->daemon = daemon;
|
||||||
lc->local_chan = local_chan;
|
lc->local_chan = local_chan;
|
||||||
lc->even_if_identical = even_if_identical;
|
lc->even_if_identical = even_if_identical;
|
||||||
|
lc->even_if_too_soon = false;
|
||||||
|
|
||||||
prev = cast_const(u8 *,
|
prev = cast_const(u8 *,
|
||||||
gossip_store_get(tmpctx, daemon->rstate->gs,
|
gossip_store_get(tmpctx, daemon->rstate->gs,
|
||||||
|
@ -546,6 +558,7 @@ bool handle_local_channel_update(struct daemon *daemon,
|
||||||
|
|
||||||
lc->daemon = daemon;
|
lc->daemon = daemon;
|
||||||
lc->even_if_identical = false;
|
lc->even_if_identical = false;
|
||||||
|
lc->even_if_too_soon = false;
|
||||||
|
|
||||||
/* FIXME: We should get scid from lightningd when setting up the
|
/* FIXME: We should get scid from lightningd when setting up the
|
||||||
* connection, so no per-peer daemon can mess with channels other than
|
* connection, so no per-peer daemon can mess with channels other than
|
||||||
|
|
|
@ -68,6 +68,9 @@ void *notleak_(const void *ptr UNNEEDED, bool plus_children UNNEEDED)
|
||||||
/* Generated stub for queue_peer_msg */
|
/* Generated stub for queue_peer_msg */
|
||||||
void queue_peer_msg(struct peer *peer UNNEEDED, const u8 *msg TAKES UNNEEDED)
|
void queue_peer_msg(struct peer *peer UNNEEDED, const u8 *msg TAKES UNNEEDED)
|
||||||
{ fprintf(stderr, "queue_peer_msg called!\n"); abort(); }
|
{ fprintf(stderr, "queue_peer_msg called!\n"); abort(); }
|
||||||
|
/* Generated stub for reltimer_arg */
|
||||||
|
void *reltimer_arg(struct oneshot *t UNNEEDED)
|
||||||
|
{ fprintf(stderr, "reltimer_arg called!\n"); abort(); }
|
||||||
/* Generated stub for status_failed */
|
/* Generated stub for status_failed */
|
||||||
void status_failed(enum status_failreason code UNNEEDED,
|
void status_failed(enum status_failreason code UNNEEDED,
|
||||||
const char *fmt UNNEEDED, ...)
|
const char *fmt UNNEEDED, ...)
|
||||||
|
|
|
@ -107,6 +107,9 @@ void queue_peer_from_store(struct peer *peer UNNEEDED,
|
||||||
/* Generated stub for queue_peer_msg */
|
/* Generated stub for queue_peer_msg */
|
||||||
void queue_peer_msg(struct peer *peer UNNEEDED, const u8 *msg TAKES UNNEEDED)
|
void queue_peer_msg(struct peer *peer UNNEEDED, const u8 *msg TAKES UNNEEDED)
|
||||||
{ fprintf(stderr, "queue_peer_msg called!\n"); abort(); }
|
{ fprintf(stderr, "queue_peer_msg called!\n"); abort(); }
|
||||||
|
/* Generated stub for reltimer_arg */
|
||||||
|
void *reltimer_arg(struct oneshot *t UNNEEDED)
|
||||||
|
{ fprintf(stderr, "reltimer_arg called!\n"); abort(); }
|
||||||
/* Generated stub for status_failed */
|
/* Generated stub for status_failed */
|
||||||
void status_failed(enum status_failreason code UNNEEDED,
|
void status_failed(enum status_failreason code UNNEEDED,
|
||||||
const char *fmt UNNEEDED, ...)
|
const char *fmt UNNEEDED, ...)
|
||||||
|
|
Loading…
Add table
Reference in a new issue