common: add ability for gossip_store to track by timestamp.

We'll use this to keep a two-hour-ago "recent gossip offset" as an
optimization.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-07-15 15:29:26 +09:30
parent dcf2916dcb
commit 62a5183fb5
2 changed files with 100 additions and 3 deletions

View File

@ -49,6 +49,64 @@ static size_t reopen_gossip_store(int *gossip_store_fd, const u8 *msg)
return equivalent_offset;
}
static bool public_msg_type(enum peer_wire type)
{
/* This switch statement makes you think about new types as they
* are introduced. */
switch (type) {
case WIRE_INIT:
case WIRE_ERROR:
case WIRE_WARNING:
case WIRE_PING:
case WIRE_PONG:
case WIRE_TX_ADD_INPUT:
case WIRE_TX_ADD_OUTPUT:
case WIRE_TX_REMOVE_INPUT:
case WIRE_TX_REMOVE_OUTPUT:
case WIRE_TX_COMPLETE:
case WIRE_TX_SIGNATURES:
case WIRE_OPEN_CHANNEL:
case WIRE_ACCEPT_CHANNEL:
case WIRE_FUNDING_CREATED:
case WIRE_FUNDING_SIGNED:
case WIRE_FUNDING_LOCKED:
case WIRE_OPEN_CHANNEL2:
case WIRE_ACCEPT_CHANNEL2:
case WIRE_INIT_RBF:
case WIRE_ACK_RBF:
case WIRE_SHUTDOWN:
case WIRE_CLOSING_SIGNED:
case WIRE_UPDATE_ADD_HTLC:
case WIRE_UPDATE_FULFILL_HTLC:
case WIRE_UPDATE_FAIL_HTLC:
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
case WIRE_COMMITMENT_SIGNED:
case WIRE_REVOKE_AND_ACK:
case WIRE_UPDATE_FEE:
case WIRE_UPDATE_BLOCKHEIGHT:
case WIRE_CHANNEL_REESTABLISH:
case WIRE_ANNOUNCEMENT_SIGNATURES:
case WIRE_QUERY_SHORT_CHANNEL_IDS:
case WIRE_REPLY_SHORT_CHANNEL_IDS_END:
case WIRE_QUERY_CHANNEL_RANGE:
case WIRE_REPLY_CHANNEL_RANGE:
case WIRE_GOSSIP_TIMESTAMP_FILTER:
case WIRE_OBS2_ONION_MESSAGE:
case WIRE_ONION_MESSAGE:
#if EXPERIMENTAL_FEATURES
case WIRE_STFU:
#endif
return false;
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_NODE_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
return true;
}
/* Actually, we do have other (internal) messages. */
return false;
}
u8 *gossip_store_next(const tal_t *ctx,
int *gossip_store_fd,
u32 timestamp_min, u32 timestamp_max,
@ -111,9 +169,7 @@ u8 *gossip_store_next(const tal_t *ctx,
*off = *end = reopen_gossip_store(gossip_store_fd, msg);
msg = tal_free(msg);
/* Ignore gossipd internal messages. */
} else if (type != WIRE_CHANNEL_ANNOUNCEMENT
&& type != WIRE_CHANNEL_UPDATE
&& type != WIRE_NODE_ANNOUNCEMENT) {
} else if (!public_msg_type(type)) {
msg = tal_free(msg);
} else if (!push && push_only) {
msg = tal_free(msg);
@ -148,3 +204,38 @@ size_t find_gossip_store_end(int gossip_store_fd, size_t off)
}
return off;
}
/* Keep seeking forward until we hit something >= timestamp */
size_t find_gossip_store_by_timestamp(int gossip_store_fd,
size_t off,
u32 timestamp)
{
/* We cheat and read first two bytes of message too. */
struct {
struct gossip_hdr hdr;
be16 type;
} buf;
int r;
while ((r = pread(gossip_store_fd, &buf,
sizeof(buf.hdr) + sizeof(buf.type), off))
== sizeof(buf.hdr) + sizeof(buf.type)) {
u32 msglen = be32_to_cpu(buf.hdr.len) & GOSSIP_STORE_LEN_MASK;
u16 type = be16_to_cpu(buf.type);
/* Don't swallow end marker! Reset, as they will call
* gossip_store_next and reopen file. */
if (type == WIRE_GOSSIP_STORE_ENDED)
return 1;
/* Only to-be-broadcast types have valid timestamps! */
if (!(be32_to_cpu(buf.hdr.len) & GOSSIP_STORE_LEN_DELETED_BIT)
&& public_msg_type(type)
&& be32_to_cpu(buf.hdr.timestamp) >= timestamp) {
break;
}
off += sizeof(buf.hdr) + msglen;
}
return off;
}

View File

@ -63,4 +63,10 @@ u8 *gossip_store_next(const tal_t *ctx,
*/
size_t find_gossip_store_end(int gossip_store_fd, size_t old_end);
/**
* Return offset of first entry >= this timestamp.
*/
size_t find_gossip_store_by_timestamp(int gossip_store_fd,
size_t off,
u32 timestamp);
#endif /* LIGHTNING_COMMON_GOSSIP_STORE_H */