Skip to content

Commit e14cae9

Browse files
committed
gossip_store: wait for completed bit on reading.
Signed-off-by: Rusty Russell <[email protected]>
1 parent a58bab3 commit e14cae9

File tree

4 files changed

+29
-21
lines changed

4 files changed

+29
-21
lines changed

common/gossip_store.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ bool gossip_store_readhdr(int gossip_store_fd, size_t off,
3030
r = pread(gossip_store_fd, &buf, HDR_AND_TYPE_SIZE, off);
3131
if (r != HDR_AND_TYPE_SIZE)
3232
return false;
33+
if (!(buf.hdr.flags & CPU_TO_BE16(GOSSIP_STORE_COMPLETED_BIT)))
34+
return false;
3335
*len = be16_to_cpu(buf.hdr.len);
3436
if (flags)
3537
*flags = be16_to_cpu(buf.hdr.flags);

common/gossmap.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -694,10 +694,15 @@ static bool map_catchup(struct gossmap *map, bool must_be_clean, bool *changed)
694694
reclen = msglen + sizeof(ghdr);
695695

696696
flags = be16_to_cpu(ghdr.flags);
697+
698+
/* Not finished, this can happen. */
699+
if (!(flags & GOSSIP_STORE_COMPLETED_BIT))
700+
break;
701+
697702
if (flags & GOSSIP_STORE_DELETED_BIT)
698703
continue;
699704

700-
/* Partial write, this can happen. */
705+
/* Partial write, should not happen with completed records. */
701706
if (map->map_end + reclen > map->map_size)
702707
break;
703708

contrib/pyln-client/pyln/client/gossmap.py

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -392,8 +392,7 @@ class Gossmap(object):
392392
def __init__(self, store_filename: str = "gossip_store"):
393393
self.store_filename = store_filename
394394
self.store_file = open(store_filename, "rb")
395-
self.store_buf = bytes()
396-
self.bytes_read = 0
395+
self.bytes_read = 1
397396
self.nodes: Dict[GossmapNodeId, GossmapNode] = {}
398397
self.channels: Dict[ShortChannelId, GossmapChannel] = {}
399398
self._last_scid: Optional[str] = None
@@ -592,24 +591,24 @@ def _remove_channel_by_deletemsg(self, rec: bytes):
592591
if scid in self.channels:
593592
self._del_channel(scid)
594593

595-
def _pull_bytes(self, length: int) -> bool:
596-
"""Pull bytes from file into our internal buffer"""
597-
if len(self.store_buf) < length:
598-
self.store_buf += self.store_file.read(length - len(self.store_buf))
599-
self.bytes_read += len(self.store_buf)
600-
return len(self.store_buf) >= length
601-
602594
def _read_record(self) -> Optional[bytes]:
603-
"""If a whole record is not in the file, returns None.
604-
If deleted, returns empty."""
605-
off = self.bytes_read + 1
606-
if not self._pull_bytes(12):
595+
"""If a whole record is not in the file, returns None, None."""
596+
prev_off = self.bytes_read
597+
hdr = self.store_file.read(12)
598+
if len(hdr) != 12:
599+
self.store_file.seek(prev_offset)
600+
return None, None
601+
hdr = GossipStoreMsgHeader(hdr, prev_off)
602+
rec = self.store_file.read(hdr.length)
603+
if len(rec) != hdr.length:
604+
self.store_file.seek(prev_offset)
607605
return None, None
608-
hdr = GossipStoreMsgHeader(self.store_buf[:12], off)
609-
if not self._pull_bytes(12 + hdr.length):
610-
return None, hdr
611-
rec = self.store_buf[12:]
612-
self.store_buf = bytes()
606+
if (hdr.flags & GOSSIP_STORE_LEN_COMPLETE_BIT) == 0:
607+
self.store_file.seek(prev_offset)
608+
return None, None
609+
610+
# Ok, we're digesting this one, so increment bytes_read.
611+
self.bytes_read += hdr.length + len(rec)
613612
return rec, hdr
614613

615614
def refresh(self):

devtools/dump-gossipstore.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,21 @@ int main(int argc, char *argv[])
6767
u16 flags = be16_to_cpu(hdr.flags);
6868
u16 msglen = be16_to_cpu(hdr.len);
6969
u8 *msg, *inner;
70-
bool deleted, dying;
70+
bool deleted, dying, complete;
7171
u32 blockheight;
7272

7373
deleted = (flags & GOSSIP_STORE_DELETED_BIT);
7474
dying = (flags & GOSSIP_STORE_DYING_BIT);
75+
complete = (flags & GOSSIP_STORE_COMPLETED_BIT);
7576

7677
msg = tal_arr(NULL, u8, msglen);
7778
if (read(fd, msg, msglen) != msglen)
7879
errx(1, "%zu: Truncated file?", off);
7980

80-
printf("%zu: %s%s%s", off,
81+
printf("%zu: %s%s%s%s", off,
8182
deleted ? "DELETED " : "",
8283
dying ? "DYING " : "",
84+
complete ? "" : "**INCOMPLETE** ",
8385
be32_to_cpu(hdr.crc) != crc32c(be32_to_cpu(hdr.timestamp), msg, msglen) ? "**BAD CHECKSUM** " : "");
8486

8587
if (print_timestamp)

0 commit comments

Comments
 (0)