Browse Source

gossipd: new struct to hold scids and timestamps together.

It's not (yet?) compulsory to have the timestamps, but handing them around
together makes sense (a missing timestamp has the same effect as a zero
timestamp).

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-prep
Rusty Russell 4 years ago
committed by neil saitug
parent
commit
8db5fb7345
  1. 3
      gossipd/gossipd.c
  2. 12
      gossipd/gossipd.h
  3. 88
      gossipd/queries.c
  4. 3
      gossipd/queries.h
  5. 16
      gossipd/seeker.c
  6. 3
      gossipd/test/run-next_block_range.c

3
gossipd/gossipd.c

@ -64,7 +64,6 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/un.h> #include <sys/un.h>
#include <unistd.h> #include <unistd.h>
#include <wire/peer_wire.h>
#include <wire/wire_io.h> #include <wire/wire_io.h>
#include <wire/wire_sync.h> #include <wire/wire_sync.h>
@ -606,7 +605,7 @@ static struct io_plan *connectd_new_peer(struct io_conn *conn,
peer->scid_query_nodes = NULL; peer->scid_query_nodes = NULL;
peer->scid_query_nodes_idx = 0; peer->scid_query_nodes_idx = 0;
peer->scid_query_outstanding = false; peer->scid_query_outstanding = false;
peer->query_channel_scids = NULL; peer->range_replies = NULL;
peer->query_channel_range_cb = NULL; peer->query_channel_range_cb = NULL;
peer->num_pings_outstanding = 0; peer->num_pings_outstanding = 0;

12
gossipd/gossipd.h

@ -7,6 +7,7 @@
#include <ccan/timer/timer.h> #include <ccan/timer/timer.h>
#include <common/bigsize.h> #include <common/bigsize.h>
#include <common/node_id.h> #include <common/node_id.h>
#include <wire/peer_wire.h>
/* We talk to `hsmd` to sign our gossip messages with the node key */ /* We talk to `hsmd` to sign our gossip messages with the node key */
#define HSM_FD 3 #define HSM_FD 3
@ -61,6 +62,11 @@ struct daemon {
struct feature_set *our_features; struct feature_set *our_features;
}; };
struct range_query_reply {
struct short_channel_id scid;
struct channel_update_timestamps ts;
};
/* This represents each peer we're gossiping with */ /* This represents each peer we're gossiping with */
struct peer { struct peer {
/* daemon->peers */ /* daemon->peers */
@ -97,12 +103,10 @@ struct peer {
/* What we're querying: [range_first_blocknum, range_end_blocknum) */ /* What we're querying: [range_first_blocknum, range_end_blocknum) */
u32 range_first_blocknum, range_end_blocknum; u32 range_first_blocknum, range_end_blocknum;
u32 range_prev_end_blocknum; u32 range_prev_end_blocknum;
struct short_channel_id *query_channel_scids; struct range_query_reply *range_replies;
struct channel_update_timestamps *query_channel_timestamps;
void (*query_channel_range_cb)(struct peer *peer, void (*query_channel_range_cb)(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks, u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids, const struct range_query_reply *replies,
const struct channel_update_timestamps *,
bool complete); bool complete);
/* The daemon_conn used to queue messages to/from the peer. */ /* The daemon_conn used to queue messages to/from the peer. */

88
gossipd/queries.c

@ -628,6 +628,43 @@ const u8 *handle_query_channel_range(struct peer *peer, const u8 *msg)
return NULL; return NULL;
} }
/* Append these scids (and optional timestamps) to our pending replies */
static u8 *append_range_reply(struct peer *peer,
const struct short_channel_id *scids,
const struct tlv_reply_channel_range_tlvs_timestamps_tlv
*timestamps_tlv)
{
u16 i, old_num, added;
const struct channel_update_timestamps *ts;
/* Zero means "no timestamp" */
const static struct channel_update_timestamps zero_ts;
if (timestamps_tlv) {
ts = decode_channel_update_timestamps(tmpctx,
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 = NULL;
old_num = tal_count(peer->range_replies);
added = tal_count(scids);
for (i = 0; i < added; i++) {
tal_resize(&peer->range_replies, old_num + i + 1);
peer->range_replies[old_num + i].scid = scids[i];
if (ts)
peer->range_replies[old_num + i].ts = ts[i];
else
peer->range_replies[old_num + i].ts = zero_ts;
}
return NULL;
}
/*~ This is the reply we get when we send query_channel_range; we keep /*~ This is the reply we get when we send query_channel_range; we keep
* expecting them until the entire range we asked for is covered. */ * expecting them until the entire range we asked for is covered. */
const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg) const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
@ -637,12 +674,11 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
u32 first_blocknum, number_of_blocks, start, end; u32 first_blocknum, number_of_blocks, start, end;
u8 *encoded; u8 *encoded;
struct short_channel_id *scids; struct short_channel_id *scids;
struct channel_update_timestamps *ts; const struct range_query_reply *replies;
size_t n; const u8 *err;
void (*cb)(struct peer *peer, void (*cb)(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks, u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids, const struct range_query_reply *replies,
const struct channel_update_timestamps *ts,
bool complete); bool complete);
struct tlv_reply_channel_range_tlvs *tlvs struct tlv_reply_channel_range_tlvs *tlvs
= tlv_reply_channel_range_tlvs_new(tmpctx); = tlv_reply_channel_range_tlvs_new(tmpctx);
@ -661,7 +697,7 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
tal_hex(tmpctx, msg)); tal_hex(tmpctx, msg));
} }
if (!peer->query_channel_scids) { if (!peer->range_replies) {
return towire_errorfmt(peer, NULL, return towire_errorfmt(peer, NULL,
"reply_channel_range without query: %s", "reply_channel_range without query: %s",
tal_hex(tmpctx, msg)); tal_hex(tmpctx, msg));
@ -746,47 +782,26 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
} }
peer->range_prev_end_blocknum = end; peer->range_prev_end_blocknum = end;
/* Add scids */ err = append_range_reply(peer, scids, tlvs->timestamps_tlv);
n = tal_count(peer->query_channel_scids); if (err)
tal_resize(&peer->query_channel_scids, n + tal_count(scids)); return err;
memcpy(peer->query_channel_scids + n, scids, tal_bytelen(scids));
/* Credit peer for answering gossip, so seeker doesn't get upset: /* Credit peer for answering gossip, so seeker doesn't get upset:
* since scids are only 8 bytes, use a discount over normal gossip. */ * since scids are only 8 bytes, use a discount over normal gossip. */
peer_supplied_good_gossip(peer, tal_count(scids) / 20); peer_supplied_good_gossip(peer, tal_count(scids) / 20);
/* 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? */ /* Still more to go? */
if (peer->range_prev_end_blocknum < peer->range_end_blocknum) if (peer->range_prev_end_blocknum < peer->range_end_blocknum)
return NULL; return NULL;
/* Clear these immediately in case cb want to queue more */ /* Clear these immediately in case cb want to queue more */
scids = tal_steal(tmpctx, peer->query_channel_scids); replies = tal_steal(tmpctx, peer->range_replies);
ts = tal_steal(tmpctx, peer->query_channel_timestamps);
cb = peer->query_channel_range_cb; cb = peer->query_channel_range_cb;
peer->query_channel_scids = NULL; peer->range_replies = NULL;
peer->query_channel_timestamps = NULL;
peer->query_channel_range_cb = NULL; peer->query_channel_range_cb = NULL;
cb(peer, first_blocknum, number_of_blocks, scids, ts, complete); cb(peer, first_blocknum, number_of_blocks, replies, complete);
return NULL; return NULL;
} }
@ -1009,8 +1024,7 @@ bool query_channel_range(struct daemon *daemon,
enum query_option_flags qflags, enum query_option_flags qflags,
void (*cb)(struct peer *peer, void (*cb)(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks, u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids, const struct range_query_reply *replies,
const struct channel_update_timestamps *,
bool complete)) bool complete))
{ {
u8 *msg; u8 *msg;
@ -1018,7 +1032,7 @@ bool query_channel_range(struct daemon *daemon,
assert((qflags & ~(QUERY_ADD_TIMESTAMPS|QUERY_ADD_CHECKSUMS)) == 0); assert((qflags & ~(QUERY_ADD_TIMESTAMPS|QUERY_ADD_CHECKSUMS)) == 0);
assert(peer->gossip_queries_feature); assert(peer->gossip_queries_feature);
assert(!peer->query_channel_scids); assert(!peer->range_replies);
assert(!peer->query_channel_range_cb); assert(!peer->query_channel_range_cb);
if (qflags) { if (qflags) {
@ -1038,9 +1052,7 @@ bool query_channel_range(struct daemon *daemon,
peer->range_first_blocknum = first_blocknum; peer->range_first_blocknum = first_blocknum;
peer->range_end_blocknum = first_blocknum + number_of_blocks; peer->range_end_blocknum = first_blocknum + number_of_blocks;
peer->range_prev_end_blocknum = first_blocknum-1; peer->range_prev_end_blocknum = first_blocknum-1;
peer->query_channel_scids = tal_arr(peer, struct short_channel_id, 0); peer->range_replies = tal_arr(peer, struct range_query_reply, 0);
peer->query_channel_timestamps
= tal_arr(peer, struct channel_update_timestamps, 0);
peer->query_channel_range_cb = cb; peer->query_channel_range_cb = cb;
return true; return true;

3
gossipd/queries.h

@ -42,8 +42,7 @@ bool query_channel_range(struct daemon *daemon,
enum query_option_flags qflags, enum query_option_flags qflags,
void (*cb)(struct peer *peer, void (*cb)(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks, u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids, const struct range_query_reply *replies,
const struct channel_update_timestamps *,
bool complete)); bool complete));
/* Ask this peer for info about an array of scids, with optional query_flags */ /* Ask this peer for info about an array of scids, with optional query_flags */

16
gossipd/seeker.c

@ -296,7 +296,7 @@ static bool peer_has_gossip_queries(const struct peer *peer)
static bool peer_can_take_range_query(const struct peer *peer) static bool peer_can_take_range_query(const struct peer *peer)
{ {
return peer->gossip_queries_feature return peer->gossip_queries_feature
&& !peer->query_channel_scids; && !peer->range_replies;
} }
static bool peer_can_take_scid_query(const struct peer *peer) static bool peer_can_take_scid_query(const struct peer *peer)
@ -643,8 +643,7 @@ static void check_timestamps(struct seeker *seeker,
static void process_scid_probe(struct peer *peer, static void process_scid_probe(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks, u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids, const struct range_query_reply *replies,
const struct channel_update_timestamps *ts,
bool complete) bool complete)
{ {
struct seeker *seeker = peer->daemon->seeker; struct seeker *seeker = peer->daemon->seeker;
@ -656,15 +655,16 @@ static void process_scid_probe(struct peer *peer,
clear_softref(seeker, &seeker->random_peer_softref); clear_softref(seeker, &seeker->random_peer_softref);
for (size_t i = 0; i < tal_count(scids); i++) { for (size_t i = 0; i < tal_count(replies); i++) {
struct chan *c = get_channel(seeker->daemon->rstate, &scids[i]); struct chan *c = get_channel(seeker->daemon->rstate,
&replies[i].scid);
if (c) { if (c) {
if (ts) check_timestamps(seeker, c, &replies[i].ts, peer);
check_timestamps(seeker, c, ts+i, peer);
continue; continue;
} }
new_unknown_scids |= add_unknown_scid(seeker, &scids[i], peer); new_unknown_scids |= add_unknown_scid(seeker, &replies[i].scid,
peer);
} }
/* No new unknown scids, or no more to ask? We give some wiggle /* No new unknown scids, or no more to ask? We give some wiggle

3
gossipd/test/run-next_block_range.c

@ -39,8 +39,7 @@ bool query_channel_range(struct daemon *daemon UNNEEDED,
enum query_option_flags qflags UNNEEDED, enum query_option_flags qflags UNNEEDED,
void (*cb)(struct peer *peer UNNEEDED, void (*cb)(struct peer *peer UNNEEDED,
u32 first_blocknum UNNEEDED, u32 number_of_blocks UNNEEDED, u32 first_blocknum UNNEEDED, u32 number_of_blocks UNNEEDED,
const struct short_channel_id *scids UNNEEDED, const struct range_query_reply *replies UNNEEDED,
const struct channel_update_timestamps * UNNEEDED,
bool complete)) bool complete))
{ fprintf(stderr, "query_channel_range called!\n"); abort(); } { fprintf(stderr, "query_channel_range called!\n"); abort(); }
/* Generated stub for query_short_channel_ids */ /* Generated stub for query_short_channel_ids */

Loading…
Cancel
Save