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/un.h>
#include <unistd.h>
#include <wire/peer_wire.h>
#include <wire/wire_io.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_idx = 0;
peer->scid_query_outstanding = false;
peer->query_channel_scids = NULL;
peer->range_replies = NULL;
peer->query_channel_range_cb = NULL;
peer->num_pings_outstanding = 0;

12
gossipd/gossipd.h

@ -7,6 +7,7 @@
#include <ccan/timer/timer.h>
#include <common/bigsize.h>
#include <common/node_id.h>
#include <wire/peer_wire.h>
/* We talk to `hsmd` to sign our gossip messages with the node key */
#define HSM_FD 3
@ -61,6 +62,11 @@ struct daemon {
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 */
struct peer {
/* daemon->peers */
@ -97,12 +103,10 @@ struct peer {
/* What we're querying: [range_first_blocknum, range_end_blocknum) */
u32 range_first_blocknum, range_end_blocknum;
u32 range_prev_end_blocknum;
struct short_channel_id *query_channel_scids;
struct channel_update_timestamps *query_channel_timestamps;
struct range_query_reply *range_replies;
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 *,
const struct range_query_reply *replies,
bool complete);
/* 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;
}
/* 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
* expecting them until the entire range we asked for is covered. */
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;
u8 *encoded;
struct short_channel_id *scids;
struct channel_update_timestamps *ts;
size_t n;
const struct range_query_reply *replies;
const u8 *err;
void (*cb)(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids,
const struct channel_update_timestamps *ts,
const struct range_query_reply *replies,
bool complete);
struct tlv_reply_channel_range_tlvs *tlvs
= 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));
}
if (!peer->query_channel_scids) {
if (!peer->range_replies) {
return towire_errorfmt(peer, NULL,
"reply_channel_range without query: %s",
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;
/* Add scids */
n = tal_count(peer->query_channel_scids);
tal_resize(&peer->query_channel_scids, n + tal_count(scids));
memcpy(peer->query_channel_scids + n, scids, tal_bytelen(scids));
err = append_range_reply(peer, scids, tlvs->timestamps_tlv);
if (err)
return err;
/* Credit peer for answering gossip, so seeker doesn't get upset:
* since scids are only 8 bytes, use a discount over normal gossip. */
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? */
if (peer->range_prev_end_blocknum < peer->range_end_blocknum)
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);
replies = tal_steal(tmpctx, peer->range_replies);
cb = peer->query_channel_range_cb;
peer->query_channel_scids = NULL;
peer->query_channel_timestamps = NULL;
peer->range_replies = 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;
}
@ -1009,8 +1024,7 @@ bool query_channel_range(struct daemon *daemon,
enum query_option_flags qflags,
void (*cb)(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids,
const struct channel_update_timestamps *,
const struct range_query_reply *replies,
bool complete))
{
u8 *msg;
@ -1018,7 +1032,7 @@ bool query_channel_range(struct daemon *daemon,
assert((qflags & ~(QUERY_ADD_TIMESTAMPS|QUERY_ADD_CHECKSUMS)) == 0);
assert(peer->gossip_queries_feature);
assert(!peer->query_channel_scids);
assert(!peer->range_replies);
assert(!peer->query_channel_range_cb);
if (qflags) {
@ -1038,9 +1052,7 @@ bool query_channel_range(struct daemon *daemon,
peer->range_first_blocknum = first_blocknum;
peer->range_end_blocknum = first_blocknum + number_of_blocks;
peer->range_prev_end_blocknum = first_blocknum-1;
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->range_replies = tal_arr(peer, struct range_query_reply, 0);
peer->query_channel_range_cb = cb;
return true;

3
gossipd/queries.h

@ -42,8 +42,7 @@ bool query_channel_range(struct daemon *daemon,
enum query_option_flags qflags,
void (*cb)(struct peer *peer,
u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids,
const struct channel_update_timestamps *,
const struct range_query_reply *replies,
bool complete));
/* 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)
{
return peer->gossip_queries_feature
&& !peer->query_channel_scids;
&& !peer->range_replies;
}
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,
u32 first_blocknum, u32 number_of_blocks,
const struct short_channel_id *scids,
const struct channel_update_timestamps *ts,
const struct range_query_reply *replies,
bool complete)
{
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);
for (size_t i = 0; i < tal_count(scids); i++) {
struct chan *c = get_channel(seeker->daemon->rstate, &scids[i]);
for (size_t i = 0; i < tal_count(replies); i++) {
struct chan *c = get_channel(seeker->daemon->rstate,
&replies[i].scid);
if (c) {
if (ts)
check_timestamps(seeker, c, ts+i, peer);
check_timestamps(seeker, c, &replies[i].ts, peer);
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

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,
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,
const struct range_query_reply *replies UNNEEDED,
bool complete))
{ fprintf(stderr, "query_channel_range called!\n"); abort(); }
/* Generated stub for query_short_channel_ids */

Loading…
Cancel
Save