From ef59a8f4aa39ba1ce4ab44523a8bab0f9cd0da2a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 3 Jul 2018 06:24:12 +0930 Subject: [PATCH] gossipd: suppress redundant local updates which we would generate. This doesn't do anything for us now, since we actually tend to produce DISABLE/ENABLE update pairs. But the infrastructure is useful for the next patch. We also add more details to the trace message in the core update code. Signed-off-by: Rusty Russell --- gossipd/gossip.c | 34 ++++++++++++++++++++++++++++++++++ gossipd/routing.c | 5 ++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 00f32556d..29a644e42 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -1656,6 +1656,21 @@ static u8 *create_channel_update(const tal_t *ctx, return update; } +/* Return true if the only change would be the timestamp. */ +static bool update_redundant(const struct half_chan *hc, + bool disable, u16 cltv_delta, u64 htlc_minimum_msat, + u32 fee_base_msat, u32 fee_proportional_millionths) +{ + if (!is_halfchan_defined(hc)) + return false; + + return !(hc->flags & ROUTING_FLAGS_DISABLED) == !disable + && hc->delay == cltv_delta + && hc->htlc_minimum_msat == htlc_minimum_msat + && hc->base_fee == fee_base_msat + && hc->proportional_fee == fee_proportional_millionths; +} + static void handle_local_channel_update(struct peer *peer, const u8 *msg) { struct short_channel_id scid; @@ -1701,6 +1716,25 @@ static void handle_local_channel_update(struct peer *peer, const u8 *msg) return; } + /* Avoid redundant updates on public channels: on non-public channels + * we'd need to consider pending updates, so don't bother. */ + if (is_chan_public(chan) + && update_redundant(&chan->half[direction], + disable, cltv_delta, htlc_minimum_msat, + fee_base_msat, fee_proportional_millionths)) { + status_trace("Suppressing redundant channel update for %s:(%u) %s %"PRIu64"/%u vs %u/%u", + type_to_string(tmpctx, struct short_channel_id, + &scid), + direction, + is_halfchan_defined(&chan->half[direction]) + ? (chan->half[direction].flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE") + : "UNDEFINED", + chan->half[direction].last_timestamp, + (u32)time_now().ts.tv_sec, + chan->half[direction].flags, disable); + return; + } + cupdate = create_channel_update(tmpctx, peer->daemon->rstate, chan, direction, disable, cltv_delta, diff --git a/gossipd/routing.c b/gossipd/routing.c index 0a4b74d40..8feb60d93 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -1207,11 +1207,14 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update, return err; } - status_trace("Received channel_update for channel %s(%d) now %s (from %s)", + status_trace("Received channel_update for channel %s(%d) now %s was %s (from %s)", type_to_string(tmpctx, struct short_channel_id, &short_channel_id), flags & 0x01, flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE", + is_halfchan_defined(c) + ? (c->flags & ROUTING_FLAGS_DISABLED ? "DISABLED" : "ACTIVE") + : "UNDEFINED", source); if (!routing_add_channel_update(rstate, serialized))