| 1060 | } |
| 1061 | |
| 1062 | static struct command_result *channels_refresh(struct command *cmd, |
| 1063 | struct table_desc *td, |
| 1064 | struct db_query *dbq) |
| 1065 | { |
| 1066 | struct sql *sql = sql_of(cmd->plugin); |
| 1067 | struct out_req *req; |
| 1068 | size_t msglen; |
| 1069 | u16 type, flags; |
| 1070 | |
| 1071 | if (sql->gosstore_fd == -1) { |
| 1072 | sql->gosstore_fd = open("gossip_store", O_RDONLY); |
| 1073 | if (sql->gosstore_fd == -1) |
| 1074 | plugin_err(cmd->plugin, "Could not open gossip_store: %s", |
| 1075 | strerror(errno)); |
| 1076 | } |
| 1077 | |
| 1078 | /* First time, set off to end and load from scratch */ |
| 1079 | if (sql->gosstore_channels_off == 0) { |
| 1080 | sql->gosstore_channels_off = find_gossip_store_end(sql->gosstore_fd, 1); |
| 1081 | return default_refresh(cmd, td, dbq); |
| 1082 | } |
| 1083 | |
| 1084 | plugin_log(cmd->plugin, LOG_DBG, "Refreshing channels @%zu...", |
| 1085 | sql->gosstore_channels_off); |
| 1086 | |
| 1087 | /* OK, try catching up! */ |
| 1088 | while (gossip_store_readhdr(sql->gosstore_fd, sql->gosstore_channels_off, |
| 1089 | &msglen, NULL, &flags, &type)) { |
| 1090 | struct short_channel_id scid; |
| 1091 | size_t off = sql->gosstore_channels_off; |
| 1092 | |
| 1093 | sql->gosstore_channels_off += sizeof(struct gossip_hdr) + msglen; |
| 1094 | |
| 1095 | if (flags & GOSSIP_STORE_DELETED_BIT) |
| 1096 | continue; |
| 1097 | |
| 1098 | if (type == WIRE_GOSSIP_STORE_ENDED) { |
| 1099 | /* Force a reopen */ |
| 1100 | sql->gosstore_channels_off = sql->gosstore_nodes_off = 0; |
| 1101 | close(sql->gosstore_fd); |
| 1102 | sql->gosstore_fd = -1; |
| 1103 | return channels_refresh(cmd, td, dbq); |
| 1104 | } |
| 1105 | |
| 1106 | /* If we see a channel_announcement, we don't care until we |
| 1107 | * see the channel_update */ |
| 1108 | if (type == WIRE_CHANNEL_UPDATE |
| 1109 | || type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE_OBS) { |
| 1110 | /* This can fail if entry not fully written yet. */ |
| 1111 | if (!extract_scid(sql->gosstore_fd, off, type, &scid)) { |
| 1112 | sql->gosstore_channels_off = off; |
| 1113 | break; |
| 1114 | } |
| 1115 | |
| 1116 | plugin_log(cmd->plugin, LOG_DBG, "Refreshing channel: %s", |
| 1117 | fmt_short_channel_id(tmpctx, scid)); |
| 1118 | /* FIXME: sqlite3 version 3.24.0 (2018-06-04) added |
| 1119 | * UPSERT, but we don't require it. */ |
no test coverage detected