| 602 | } |
| 603 | |
| 604 | static bool map_catchup(struct gossmap *map, size_t *num_rejected) |
| 605 | { |
| 606 | size_t reclen; |
| 607 | bool changed = false; |
| 608 | size_t num_bad = 0; |
| 609 | |
| 610 | for (; map->map_end + sizeof(struct gossip_hdr) < map->map_size; |
| 611 | map->map_end += reclen) { |
| 612 | struct gossip_hdr ghdr; |
| 613 | size_t off; |
| 614 | u16 type; |
| 615 | |
| 616 | map_copy(map, map->map_end, &ghdr, sizeof(ghdr)); |
| 617 | reclen = (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_MASK) |
| 618 | + sizeof(ghdr); |
| 619 | |
| 620 | if (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_DELETED_BIT) |
| 621 | continue; |
| 622 | |
| 623 | /* Partial write, this can happen. */ |
| 624 | if (map->map_end + reclen > map->map_size) |
| 625 | break; |
| 626 | |
| 627 | off = map->map_end + sizeof(ghdr); |
| 628 | type = map_be16(map, off); |
| 629 | if (type == WIRE_CHANNEL_ANNOUNCEMENT) |
| 630 | add_channel(map, off, false); |
| 631 | else if (type == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL) |
| 632 | add_channel(map, off + 2 + 8 + 2, true); |
| 633 | else if (type == WIRE_CHANNEL_UPDATE) |
| 634 | num_bad += !update_channel(map, off); |
| 635 | else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE) |
| 636 | num_bad += !update_channel(map, off + 2 + 2); |
| 637 | else if (type == WIRE_GOSSIP_STORE_DELETE_CHAN) |
| 638 | remove_channel_by_deletemsg(map, off); |
| 639 | else if (type == WIRE_NODE_ANNOUNCEMENT) |
| 640 | node_announcement(map, off); |
| 641 | else if (type == WIRE_GOSSIP_STORE_ENDED) |
| 642 | reopen_store(map, off); |
| 643 | else |
| 644 | continue; |
| 645 | |
| 646 | changed = true; |
| 647 | } |
| 648 | |
| 649 | if (num_rejected) |
| 650 | *num_rejected = num_bad; |
| 651 | return changed; |
| 652 | } |
| 653 | |
| 654 | static bool load_gossip_store(struct gossmap *map, size_t *num_rejected) |
| 655 | { |
no test coverage detected