diff --git a/gossipd/gossip_generation.c b/gossipd/gossip_generation.c index 555a6150c..1baddd1fc 100644 --- a/gossipd/gossip_generation.c +++ b/gossipd/gossip_generation.c @@ -392,7 +392,7 @@ static void update_local_channel(struct local_cupdate *lc /* frees! */) msg = handle_channel_update(daemon->rstate, update, find_peer(daemon, &chan->nodes[!direction]->id), - NULL); + NULL, true); if (msg) status_failed(STATUS_FAIL_INTERNAL_ERROR, "%s: rejected local channel update %s: %s", diff --git a/gossipd/gossip_store.c b/gossipd/gossip_store.c index 238677d58..1f7aec848 100644 --- a/gossipd/gossip_store.c +++ b/gossipd/gossip_store.c @@ -829,7 +829,7 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs) case WIRE_CHANNEL_UPDATE: if (!routing_add_channel_update(rstate, take(msg), gs->len, - NULL)) { + NULL, false)) { bad = "Bad channel_update"; goto badmsg; } diff --git a/gossipd/gossipd.c b/gossipd/gossipd.c index d6906ff41..e85a9c59c 100644 --- a/gossipd/gossipd.c +++ b/gossipd/gossipd.c @@ -268,7 +268,7 @@ static u8 *handle_channel_update_msg(struct peer *peer, const u8 *msg) unknown_scid.u64 = 0; err = handle_channel_update(peer->daemon->rstate, msg, peer, - &unknown_scid); + &unknown_scid, false); if (err) { if (unknown_scid.u64 != 0) query_unknown_channel(peer->daemon, peer, &unknown_scid); @@ -1797,7 +1797,7 @@ static struct io_plan *handle_payment_failure(struct io_conn *conn, tal_hex(tmpctx, channel_update), tal_hex(tmpctx, error)); u8 *err = handle_channel_update(daemon->rstate, channel_update, - NULL, NULL); + NULL, NULL, true); if (err) { status_info("extracted bad channel_update %s from onionreply %s", sanitize_error(err, err, NULL), diff --git a/gossipd/routing.c b/gossipd/routing.c index ded1f59bc..e0f3dd478 100644 --- a/gossipd/routing.c +++ b/gossipd/routing.c @@ -1674,10 +1674,10 @@ bool routing_add_channel_announcement(struct routing_state *rstate, /* If we had private updates, they'll immediately create the channel. */ if (private_updates[0]) routing_add_channel_update(rstate, take(private_updates[0]), 0, - peer); + peer, false); if (private_updates[1]) routing_add_channel_update(rstate, take(private_updates[1]), 0, - peer); + peer, false); return true; } @@ -1872,7 +1872,7 @@ static void process_pending_channel_update(struct daemon *daemon, if (!cupdate) return; - err = handle_channel_update(rstate, cupdate, peer, NULL); + err = handle_channel_update(rstate, cupdate, peer, NULL, false); if (err) { /* FIXME: We could send this error back to peer if != NULL */ status_peer_debug(peer ? &peer->id : NULL, @@ -2021,7 +2021,8 @@ static void set_connection_values(struct chan *chan, bool routing_add_channel_update(struct routing_state *rstate, const u8 *update TAKES, u32 index, - struct peer *peer) + struct peer *peer, + bool ignore_timestamp) { secp256k1_ecdsa_signature signature; struct short_channel_id short_channel_id; @@ -2111,7 +2112,7 @@ bool routing_add_channel_update(struct routing_state *rstate, /* Discard older updates */ hc = &chan->half[direction]; - if (is_halfchan_defined(hc)) { + if (is_halfchan_defined(hc) && !ignore_timestamp) { /* If we're loading from store, duplicate entries are a bug. */ if (index != 0) { status_broken("gossip_store channel_update %u replaces %u!", @@ -2222,7 +2223,8 @@ bool routing_add_channel_update(struct routing_state *rstate, } status_peer_debug(peer ? &peer->id : NULL, - "Received channel_update for channel %s/%d now %s", + "Received %schannel_update for channel %s/%d now %s", + ignore_timestamp ? "(forced) " : "", type_to_string(tmpctx, struct short_channel_id, &short_channel_id), channel_flags & 0x01, @@ -2281,7 +2283,8 @@ void remove_channel_from_store(struct routing_state *rstate, u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, struct peer *peer, - struct short_channel_id *unknown_scid) + struct short_channel_id *unknown_scid, + bool force) { u8 *serialized; const struct node_id *owner; @@ -2376,7 +2379,7 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, return err; } - routing_add_channel_update(rstate, take(serialized), 0, peer); + routing_add_channel_update(rstate, take(serialized), 0, peer, force); return NULL; } diff --git a/gossipd/routing.h b/gossipd/routing.h index 60aadc0d5..dfe4aa649 100644 --- a/gossipd/routing.h +++ b/gossipd/routing.h @@ -402,7 +402,8 @@ struct chan *next_chan(const struct node *node, struct chan_map_iter *i); * (if not NULL). */ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, struct peer *peer, - struct short_channel_id *unknown_scid); + struct short_channel_id *unknown_scid, + bool force); /* Returns NULL if all OK, otherwise an error for the peer which sent. * If was_unknown is not NULL, sets it to true if that was the reason for @@ -456,7 +457,8 @@ bool routing_add_channel_announcement(struct routing_state *rstate, bool routing_add_channel_update(struct routing_state *rstate, const u8 *update TAKES, u32 index, - struct peer *peer); + struct peer *peer, + bool ignore_timestamp); /** * Add a node_announcement to the network view without checking it * diff --git a/gossipd/test/run-crc32_of_update.c b/gossipd/test/run-crc32_of_update.c index 88f1ae0c5..f9a9cd26e 100644 --- a/gossipd/test/run-crc32_of_update.c +++ b/gossipd/test/run-crc32_of_update.c @@ -58,7 +58,8 @@ struct timeabs gossip_time_now(const struct routing_state *rstate UNNEEDED) /* Generated stub for handle_channel_update */ u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *update TAKES UNNEEDED, struct peer *peer UNNEEDED, - struct short_channel_id *unknown_scid UNNEEDED) + struct short_channel_id *unknown_scid UNNEEDED, + bool force UNNEEDED) { fprintf(stderr, "handle_channel_update called!\n"); abort(); } /* Generated stub for handle_node_announcement */ u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED,