From 1f2a03f019f504512f40daf7399d79fb822f8d06 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 8 Oct 2019 11:53:24 +1030 Subject: [PATCH] gossipd: hand (any) timestamps through to callback for query_channel_range. Signed-off-by: Rusty Russell --- common/decode_array.c | 35 +++++++++++++++++++++++++++++ common/decode_array.h | 4 ++++ gossipd/gossipd.h | 3 +++ gossipd/queries.c | 27 +++++++++++++++++++++- gossipd/queries.h | 2 ++ gossipd/seeker.c | 1 + gossipd/test/run-crc32_of_update.c | 4 ++++ gossipd/test/run-extended-info.c | 4 ++++ gossipd/test/run-next_block_range.c | 1 + 9 files changed, 80 insertions(+), 1 deletion(-) diff --git a/common/decode_array.c b/common/decode_array.c index a64904a70..a5c41717b 100644 --- a/common/decode_array.c +++ b/common/decode_array.c @@ -103,3 +103,38 @@ bigsize_t *decode_scid_query_flags(const tal_t *ctx, } return NULL; } + +struct channel_update_timestamps * +decode_channel_update_timestamps(const tal_t *ctx, + const struct tlv_reply_channel_range_tlvs_timestamps_tlv *timestamps_tlv) +{ + /* Note that our parser will set this to NULL if there are no elements */ + u8 *encoded = timestamps_tlv->encoded_timestamps; + size_t max = tal_count(encoded); + struct channel_update_timestamps *ts; + + /* FIXME: BOLT #7 should have a requirements like it does for + * query_short_channel_ids_tlvs! */ + switch (timestamps_tlv->encoding_type) { + case ARR_ZLIB: + encoded = unzlib(tmpctx, encoded, max); + if (!encoded) + return NULL; + max = tal_count(encoded); + /* fall thru */ + case ARR_UNCOMPRESSED: + ts = tal_arr(ctx, struct channel_update_timestamps, 0); + while (max) { + struct channel_update_timestamps t; + fromwire_channel_update_timestamps + (cast_const2(const u8 **, &encoded), + &max, &t); + /* Sets this to NULL if it fails */ + if (!encoded) + return tal_free(ts); + tal_arr_expand(&ts, t); + } + return ts; + } + return NULL; +} diff --git a/common/decode_array.h b/common/decode_array.h index 2e642e404..f44d18990 100644 --- a/common/decode_array.h +++ b/common/decode_array.h @@ -6,6 +6,7 @@ #include struct tlv_query_short_channel_ids_tlvs_query_flags; +struct tlv_reply_channel_range_tlvs_timestamps_tlv; /* BOLT #7: * @@ -44,4 +45,7 @@ enum scid_query_flag { bigsize_t *decode_scid_query_flags(const tal_t *ctx, const struct tlv_query_short_channel_ids_tlvs_query_flags *qf); +struct channel_update_timestamps *decode_channel_update_timestamps(const tal_t *ctx, + const struct tlv_reply_channel_range_tlvs_timestamps_tlv *timestamps_tlv); + #endif /* LIGHTNING_COMMON_DECODE_ARRAY_H */ diff --git a/gossipd/gossipd.h b/gossipd/gossipd.h index 0e5d102a2..6cd706910 100644 --- a/gossipd/gossipd.h +++ b/gossipd/gossipd.h @@ -15,6 +15,7 @@ #define CONNECTD_FD 4 struct chan; +struct channel_update_timestamps; struct broadcastable; struct seeker; @@ -103,9 +104,11 @@ struct peer { u32 range_first_blocknum, range_end_blocknum; u32 range_blocks_remaining; struct short_channel_id *query_channel_scids; + struct channel_update_timestamps *query_channel_timestamps; void (*query_channel_range_cb)(struct peer *peer, u32 first_blocknum, u32 number_of_blocks, const struct short_channel_id *scids, + const struct channel_update_timestamps *, bool complete); /* Are we asking this peer to give us gossip? */ diff --git a/gossipd/queries.c b/gossipd/queries.c index d927c019f..8408e58d5 100644 --- a/gossipd/queries.c +++ b/gossipd/queries.c @@ -637,11 +637,13 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg) u32 first_blocknum, number_of_blocks, start, end; u8 *encoded; struct short_channel_id *scids; + struct channel_update_timestamps *ts; size_t n; unsigned long b; void (*cb)(struct peer *peer, u32 first_blocknum, u32 number_of_blocks, const struct short_channel_id *scids, + const struct channel_update_timestamps *ts, bool complete); struct tlv_reply_channel_range_tlvs *tlvs = tlv_reply_channel_range_tlvs_new(tmpctx); @@ -741,20 +743,40 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg) tal_resize(&peer->query_channel_scids, n + tal_count(scids)); memcpy(peer->query_channel_scids + n, scids, tal_bytelen(scids)); + /* Add timestamps (if any), or zeroes */ + if (tlvs->timestamps_tlv) { + ts = decode_channel_update_timestamps(tlvs, + tlvs->timestamps_tlv); + if (!ts || tal_count(ts) != tal_count(scids)) { + return towire_errorfmt(peer, NULL, + "reply_channel_range %zu timestamps when %zu scids?", + tal_count(ts), + tal_count(scids)); + } + } else { + ts = tal_arrz(tlvs, struct channel_update_timestamps, + tal_count(scids)); + } + n = tal_count(peer->query_channel_timestamps); + tal_resize(&peer->query_channel_timestamps, n + tal_count(ts)); + memcpy(peer->query_channel_timestamps + n, ts, tal_bytelen(ts)); + /* Still more to go? */ if (peer->range_blocks_remaining) return NULL; /* Clear these immediately in case cb want to queue more */ scids = tal_steal(tmpctx, peer->query_channel_scids); + ts = tal_steal(tmpctx, peer->query_channel_timestamps); cb = peer->query_channel_range_cb; tal_steal(tmpctx, peer->query_channel_blocks); peer->query_channel_scids = NULL; + peer->query_channel_timestamps = NULL; peer->query_channel_blocks = NULL; peer->query_channel_range_cb = NULL; - cb(peer, first_blocknum, number_of_blocks, scids, complete); + cb(peer, first_blocknum, number_of_blocks, scids, ts, complete); return NULL; } @@ -983,6 +1005,7 @@ bool query_channel_range(struct daemon *daemon, void (*cb)(struct peer *peer, u32 first_blocknum, u32 number_of_blocks, const struct short_channel_id *scids, + const struct channel_update_timestamps *, bool complete)) { u8 *msg; @@ -1020,6 +1043,8 @@ bool query_channel_range(struct daemon *daemon, peer->query_channel_blocks = tal_arrz(peer, bitmap, BITMAP_NWORDS(number_of_blocks)); peer->query_channel_scids = tal_arr(peer, struct short_channel_id, 0); + peer->query_channel_timestamps + = tal_arr(peer, struct channel_update_timestamps, 0); peer->query_channel_range_cb = cb; return true; diff --git a/gossipd/queries.h b/gossipd/queries.h index b73a54fa3..3ddc7c639 100644 --- a/gossipd/queries.h +++ b/gossipd/queries.h @@ -3,6 +3,7 @@ #include "config.h" #include +struct channel_update_timestamps; struct daemon; struct io_conn; struct peer; @@ -42,6 +43,7 @@ bool query_channel_range(struct daemon *daemon, void (*cb)(struct peer *peer, u32 first_blocknum, u32 number_of_blocks, const struct short_channel_id *scids, + const struct channel_update_timestamps *, bool complete)); /* Ask this peer for info about an array of scids, with optional query_flags */ diff --git a/gossipd/seeker.c b/gossipd/seeker.c index 45594f981..8ddabc12e 100644 --- a/gossipd/seeker.c +++ b/gossipd/seeker.c @@ -472,6 +472,7 @@ static void peer_gossip_probe_nannounces(struct seeker *seeker) static void process_scid_probe(struct peer *peer, u32 first_blocknum, u32 number_of_blocks, const struct short_channel_id *scids, + const struct channel_update_timestamps *ts, bool complete) { struct seeker *seeker = peer->daemon->seeker; diff --git a/gossipd/test/run-crc32_of_update.c b/gossipd/test/run-crc32_of_update.c index e802f5a4f..7bef1db94 100644 --- a/gossipd/test/run-crc32_of_update.c +++ b/gossipd/test/run-crc32_of_update.c @@ -13,6 +13,10 @@ struct io_plan *daemon_conn_read_next(struct io_conn *conn UNNEEDED, /* Generated stub for daemon_conn_wake */ void daemon_conn_wake(struct daemon_conn *dc UNNEEDED) { fprintf(stderr, "daemon_conn_wake called!\n"); abort(); } +/* Generated stub for decode_channel_update_timestamps */ +struct channel_update_timestamps *decode_channel_update_timestamps(const tal_t *ctx UNNEEDED, + const struct tlv_reply_channel_range_tlvs_timestamps_tlv *timestamps_tlv UNNEEDED) +{ fprintf(stderr, "decode_channel_update_timestamps called!\n"); abort(); } /* Generated stub for decode_scid_query_flags */ bigsize_t *decode_scid_query_flags(const tal_t *ctx UNNEEDED, const struct tlv_query_short_channel_ids_tlvs_query_flags *qf UNNEEDED) diff --git a/gossipd/test/run-extended-info.c b/gossipd/test/run-extended-info.c index d125870a8..ac87a1aab 100644 --- a/gossipd/test/run-extended-info.c +++ b/gossipd/test/run-extended-info.c @@ -20,6 +20,10 @@ struct io_plan *daemon_conn_read_next(struct io_conn *conn UNNEEDED, /* Generated stub for daemon_conn_wake */ void daemon_conn_wake(struct daemon_conn *dc UNNEEDED) { fprintf(stderr, "daemon_conn_wake called!\n"); abort(); } +/* Generated stub for decode_channel_update_timestamps */ +struct channel_update_timestamps *decode_channel_update_timestamps(const tal_t *ctx UNNEEDED, + const struct tlv_reply_channel_range_tlvs_timestamps_tlv *timestamps_tlv UNNEEDED) +{ fprintf(stderr, "decode_channel_update_timestamps called!\n"); abort(); } /* Generated stub for decode_scid_query_flags */ bigsize_t *decode_scid_query_flags(const tal_t *ctx UNNEEDED, const struct tlv_query_short_channel_ids_tlvs_query_flags *qf UNNEEDED) diff --git a/gossipd/test/run-next_block_range.c b/gossipd/test/run-next_block_range.c index 55237925f..a2691120b 100644 --- a/gossipd/test/run-next_block_range.c +++ b/gossipd/test/run-next_block_range.c @@ -27,6 +27,7 @@ bool query_channel_range(struct daemon *daemon UNNEEDED, void (*cb)(struct peer *peer UNNEEDED, u32 first_blocknum UNNEEDED, u32 number_of_blocks UNNEEDED, const struct short_channel_id *scids UNNEEDED, + const struct channel_update_timestamps * UNNEEDED, bool complete)) { fprintf(stderr, "query_channel_range called!\n"); abort(); } /* Generated stub for query_short_channel_ids */