1 #include "config.h"
2 #include <assert.h>
3 #include <ccan/crypto/siphash24/siphash24.h>
4 #include <ccan/err/err.h>
5 #include <ccan/htable/htable_type.h>
6 #include <ccan/ptrint/ptrint.h>
7 #include <ccan/tal/str/str.h>
8 #include <common/features.h>
9 #include <common/gossip_store.h>
10 #include <common/gossmap.h>
11 #include <common/pseudorand.h>
12 #include <common/type_to_string.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <gossipd/gossip_store_wiregen.h>
16 #include <sys/mman.h>
17 #include <unistd.h>
18 #include <wire/peer_wire.h>
19
20 /* We need this global to decode indexes for hash functions */
21 static struct gossmap *map;
22
23 /* This makes an htable of indices into our array. */
24 static struct short_channel_id chanidx_id(const ptrint_t *pidx);
chanidx_eq_id(const ptrint_t * pidx,struct short_channel_id scid)25 static bool chanidx_eq_id(const ptrint_t *pidx,
26 struct short_channel_id scid)
27 {
28 struct short_channel_id pidxid = chanidx_id(pidx);
29 return short_channel_id_eq(&pidxid, &scid);
30 }
scid_hash(const struct short_channel_id scid)31 static size_t scid_hash(const struct short_channel_id scid)
32 {
33 return siphash24(siphash_seed(), &scid, sizeof(scid));
34 }
35 HTABLE_DEFINE_TYPE(ptrint_t, chanidx_id, scid_hash, chanidx_eq_id,
36 chanidx_htable);
37
38 static struct node_id nodeidx_id(const ptrint_t *pidx);
nodeidx_eq_id(const ptrint_t * pidx,const struct node_id id)39 static bool nodeidx_eq_id(const ptrint_t *pidx, const struct node_id id)
40 {
41 struct node_id pidxid = nodeidx_id(pidx);
42 return node_id_eq(&pidxid, &id);
43 }
nodeid_hash(const struct node_id id)44 static size_t nodeid_hash(const struct node_id id)
45 {
46 return siphash24(siphash_seed(), &id, PUBKEY_CMPR_LEN);
47 }
48 HTABLE_DEFINE_TYPE(ptrint_t, nodeidx_id, nodeid_hash, nodeidx_eq_id,
49 nodeidx_htable);
50
51 struct gossmap {
52 /* The file descriptor and filename to monitor */
53 int fd;
54 const char *fname;
55
56 /* The memory map of the file: u8 for arithmetic portability */
57 u8 *mmap;
58 /* map_end is where we read to so far, map_size is total size */
59 size_t map_end, map_size;
60
61 /* Map of node id -> node */
62 struct nodeidx_htable nodes;
63
64 /* Map of short_channel_id id -> channel */
65 struct chanidx_htable channels;
66
67 /* Array of nodes, so we can use simple index. */
68 struct gossmap_node *node_arr;
69
70 /* Array of chans, so we can use simple index */
71 struct gossmap_chan *chan_arr;
72
73 /* Linked list of freed ones, if any. */
74 u32 freed_nodes, freed_chans;
75
76 /* local messages, if any. */
77 const u8 *local;
78 };
79
80 /* Accessors for the gossmap */
map_copy(const struct gossmap * map,size_t offset,void * dst,size_t len)81 static void map_copy(const struct gossmap *map, size_t offset,
82 void *dst, size_t len)
83 {
84 if (offset >= map->map_size) {
85 size_t localoff = offset - map->map_size;
86 assert(localoff + len <= tal_bytelen(map->local));
87 memcpy(dst, map->local + localoff, len);
88 } else {
89 assert(offset + len <= map->map_size);
90 if (map->mmap)
91 memcpy(dst, map->mmap + offset, len);
92 else {
93 /* Yeah, we'll crash on I/O errors. */
94 if (pread(map->fd, dst, len, offset) != len)
95 abort();
96 }
97 }
98 }
99
map_u8(const struct gossmap * map,size_t offset)100 static u8 map_u8(const struct gossmap *map, size_t offset)
101 {
102 u8 u8;
103 map_copy(map, offset, &u8, sizeof(u8));
104 return u8;
105 }
106
map_be16(const struct gossmap * map,size_t offset)107 static u16 map_be16(const struct gossmap *map, size_t offset)
108 {
109 be16 be16;
110 map_copy(map, offset, &be16, sizeof(be16));
111 return be16_to_cpu(be16);
112 }
113
map_be32(const struct gossmap * map,size_t offset)114 static u32 map_be32(const struct gossmap *map, size_t offset)
115 {
116 be32 be32;
117 map_copy(map, offset, &be32, sizeof(be32));
118 return be32_to_cpu(be32);
119 }
120
map_be64(const struct gossmap * map,size_t offset)121 static u64 map_be64(const struct gossmap *map, size_t offset)
122 {
123 be64 be64;
124 map_copy(map, offset, &be64, sizeof(be64));
125 return be64_to_cpu(be64);
126 }
127
map_nodeid(const struct gossmap * map,size_t offset,struct node_id * id)128 static void map_nodeid(const struct gossmap *map, size_t offset,
129 struct node_id *id)
130 {
131 map_copy(map, offset, id, sizeof(*id));
132 }
133
134 /* Returns optional or compulsory feature if set, otherwise -1 */
map_feature_test(const struct gossmap * map,int compulsory_bit,size_t offset,size_t len)135 static int map_feature_test(const struct gossmap *map,
136 int compulsory_bit,
137 size_t offset, size_t len)
138 {
139 size_t bytenum = compulsory_bit / 8;
140 u8 bits;
141
142 assert(COMPULSORY_FEATURE(compulsory_bit) == compulsory_bit);
143 if (bytenum >= len)
144 return -1;
145
146 /* Note reversed! */
147 bits = map_u8(map, offset + len - 1 - bytenum);
148 if (bits & (1 << (compulsory_bit % 8)))
149 return compulsory_bit;
150 if (bits & (1 << (OPTIONAL_FEATURE(compulsory_bit) % 8)))
151 return OPTIONAL_FEATURE(compulsory_bit);
152 return -1;
153 }
154
155 /* These values can change across calls to gossmap_check. */
gossmap_max_node_idx(const struct gossmap * map)156 u32 gossmap_max_node_idx(const struct gossmap *map)
157 {
158 return tal_count(map->node_arr);
159 }
160
gossmap_max_chan_idx(const struct gossmap * map)161 u32 gossmap_max_chan_idx(const struct gossmap *map)
162 {
163 return tal_count(map->chan_arr);
164 }
165
166 /* Each channel has a unique (low) index. */
gossmap_node_idx(const struct gossmap * map,const struct gossmap_node * node)167 u32 gossmap_node_idx(const struct gossmap *map, const struct gossmap_node *node)
168 {
169 assert(node - map->node_arr < tal_count(map->node_arr));
170 return node - map->node_arr;
171 }
172
gossmap_chan_idx(const struct gossmap * map,const struct gossmap_chan * chan)173 u32 gossmap_chan_idx(const struct gossmap *map, const struct gossmap_chan *chan)
174 {
175 assert(chan - map->chan_arr < tal_count(map->chan_arr));
176 return chan - map->chan_arr;
177 }
178
179 /* htable can't handle NULL values, so we add 1 */
ptrint2chan(const ptrint_t * pidx)180 static struct gossmap_chan *ptrint2chan(const ptrint_t *pidx)
181 {
182 return map->chan_arr + ptr2int(pidx) - 1;
183 }
184
chan2ptrint(const struct gossmap_chan * chan)185 static ptrint_t *chan2ptrint(const struct gossmap_chan *chan)
186 {
187 return int2ptr(chan - map->chan_arr + 1);
188 }
189
ptrint2node(const ptrint_t * pidx)190 static struct gossmap_node *ptrint2node(const ptrint_t *pidx)
191 {
192 return map->node_arr + ptr2int(pidx) - 1;
193 }
194
node2ptrint(const struct gossmap_node * node)195 static ptrint_t *node2ptrint(const struct gossmap_node *node)
196 {
197 return int2ptr(node - map->node_arr + 1);
198 }
199
chanidx_id(const ptrint_t * pidx)200 static struct short_channel_id chanidx_id(const ptrint_t *pidx)
201 {
202 return gossmap_chan_scid(map, ptrint2chan(pidx));
203 }
204
nodeidx_id(const ptrint_t * pidx)205 static struct node_id nodeidx_id(const ptrint_t *pidx)
206 {
207 struct node_id id;
208 gossmap_node_get_id(map, ptrint2node(pidx), &id);
209 return id;
210 }
211
gossmap_find_node(const struct gossmap * map,const struct node_id * id)212 struct gossmap_node *gossmap_find_node(const struct gossmap *map,
213 const struct node_id *id)
214 {
215 ptrint_t *pi = nodeidx_htable_get(&map->nodes, *id);
216 if (pi)
217 return ptrint2node(pi);
218 return NULL;
219 }
220
gossmap_find_chan(const struct gossmap * map,const struct short_channel_id * scid)221 struct gossmap_chan *gossmap_find_chan(const struct gossmap *map,
222 const struct short_channel_id *scid)
223 {
224 ptrint_t *pi = chanidx_htable_get(&map->channels, *scid);
225 if (pi)
226 return ptrint2chan(pi);
227 return NULL;
228 }
229
init_node_arr(struct gossmap_node * node_arr,size_t start)230 static u32 init_node_arr(struct gossmap_node *node_arr, size_t start)
231 {
232 size_t i;
233 for (i = start; i < tal_count(node_arr) - 1; i++) {
234 node_arr[i].nann_off = i + 1;
235 node_arr[i].chan_idxs = NULL;
236 }
237 node_arr[i].nann_off = UINT_MAX;
238 node_arr[i].chan_idxs = NULL;
239
240 return start;
241 }
242
243 /* Freelist links through node_off of unused entries. */
next_free_node(struct gossmap * map)244 static struct gossmap_node *next_free_node(struct gossmap *map)
245 {
246 size_t f;
247
248 if (map->freed_nodes == UINT_MAX) {
249 /* Double in size, add second half to free list */
250 size_t n = tal_count(map->node_arr);
251 tal_resize(&map->node_arr, n * 2);
252 map->freed_nodes = init_node_arr(map->node_arr, n);
253 }
254
255 f = map->freed_nodes;
256 map->freed_nodes = map->node_arr[f].nann_off;
257 return &map->node_arr[f];
258 }
259
new_node(struct gossmap * map)260 static u32 new_node(struct gossmap *map)
261 {
262 struct gossmap_node *node = next_free_node(map);
263
264 assert(node->chan_idxs == NULL);
265 node->nann_off = 0;
266 node->num_chans = 0;
267
268 return gossmap_node_idx(map, node);
269 }
270
remove_node(struct gossmap * map,struct gossmap_node * node)271 static void remove_node(struct gossmap *map, struct gossmap_node *node)
272 {
273 u32 nodeidx = gossmap_node_idx(map, node);
274 if (!nodeidx_htable_del(&map->nodes, node2ptrint(node)))
275 abort();
276 node->nann_off = map->freed_nodes;
277 free(node->chan_idxs);
278 node->chan_idxs = NULL;
279 node->num_chans = 0;
280 map->freed_nodes = nodeidx;
281 }
282
node_add_channel(struct gossmap_node * node,u32 chanidx)283 static void node_add_channel(struct gossmap_node *node, u32 chanidx)
284 {
285 node->num_chans++;
286 node->chan_idxs = realloc(node->chan_idxs,
287 node->num_chans * sizeof(*node->chan_idxs));
288 node->chan_idxs[node->num_chans-1] = chanidx;
289 }
290
init_chan_arr(struct gossmap_chan * chan_arr,size_t start)291 static u32 init_chan_arr(struct gossmap_chan *chan_arr, size_t start)
292 {
293 size_t i;
294 for (i = start; i < tal_count(chan_arr) - 1; i++) {
295 chan_arr[i].cann_off = i + 1;
296 chan_arr[i].plus_scid_off = 0;
297 }
298 chan_arr[i].cann_off = UINT_MAX;
299 chan_arr[i].plus_scid_off = 0;
300 return start;
301 }
302
303 /* Freelist links through scid of unused entries. */
next_free_chan(struct gossmap * map)304 static struct gossmap_chan *next_free_chan(struct gossmap *map)
305 {
306 size_t f;
307
308 if (map->freed_chans == UINT_MAX) {
309 /* Double in size, add second half to free list */
310 size_t n = tal_count(map->chan_arr);
311 tal_resize(&map->chan_arr, n * 2);
312 map->freed_chans = init_chan_arr(map->chan_arr, n);
313 }
314
315 f = map->freed_chans;
316 map->freed_chans = map->chan_arr[f].cann_off;
317 return &map->chan_arr[f];
318 }
319
new_channel(struct gossmap * map,u32 cannounce_off,u32 plus_scid_off,bool private,u32 n1idx,u32 n2idx)320 static struct gossmap_chan *new_channel(struct gossmap *map,
321 u32 cannounce_off,
322 u32 plus_scid_off,
323 bool private,
324 u32 n1idx, u32 n2idx)
325 {
326 struct gossmap_chan *chan = next_free_chan(map);
327
328 chan->cann_off = cannounce_off;
329 chan->private = private;
330 chan->plus_scid_off = plus_scid_off;
331 chan->cupdate_off[0] = chan->cupdate_off[1] = 0;
332 memset(chan->half, 0, sizeof(chan->half));
333 chan->half[0].nodeidx = n1idx;
334 chan->half[1].nodeidx = n2idx;
335 node_add_channel(map->node_arr + n1idx, gossmap_chan_idx(map, chan));
336 node_add_channel(map->node_arr + n2idx, gossmap_chan_idx(map, chan));
337 chanidx_htable_add(&map->channels, chan2ptrint(chan));
338
339 return chan;
340 }
341
remove_chan_from_node(struct gossmap * map,struct gossmap_node * node,u32 chanidx)342 static void remove_chan_from_node(struct gossmap *map,
343 struct gossmap_node *node,
344 u32 chanidx)
345 {
346 size_t i;
347
348 if (node->num_chans == 1) {
349 remove_node(map, node);
350 return;
351 }
352 for (i = 0; node->chan_idxs[i] != chanidx; i++)
353 assert(i < node->num_chans);
354
355 memmove(node->chan_idxs + i,
356 node->chan_idxs + i + 1,
357 sizeof(node->chan_idxs[0]) * (node->num_chans - i - 1));
358 node->num_chans--;
359 }
360
gossmap_remove_chan(struct gossmap * map,struct gossmap_chan * chan)361 void gossmap_remove_chan(struct gossmap *map, struct gossmap_chan *chan)
362 {
363 u32 chanidx = gossmap_chan_idx(map, chan);
364 if (!chanidx_htable_del(&map->channels, chan2ptrint(chan)))
365 abort();
366 remove_chan_from_node(map, gossmap_nth_node(map, chan, 0), chanidx);
367 remove_chan_from_node(map, gossmap_nth_node(map, chan, 1), chanidx);
368 chan->cann_off = map->freed_chans;
369 chan->plus_scid_off = 0;
370 map->freed_chans = chanidx;
371 }
372
gossmap_remove_node(struct gossmap * map,struct gossmap_node * node)373 void gossmap_remove_node(struct gossmap *map, struct gossmap_node *node)
374 {
375 while (node->num_chans != 0)
376 gossmap_remove_chan(map, gossmap_nth_chan(map, node, 0, NULL));
377 }
378
379 /* BOLT #7:
380 * 1. type: 256 (`channel_announcement`)
381 * 2. data:
382 * * [`signature`:`node_signature_1`]
383 * * [`signature`:`node_signature_2`]
384 * * [`signature`:`bitcoin_signature_1`]
385 * * [`signature`:`bitcoin_signature_2`]
386 * * [`u16`:`len`]
387 * * [`len*byte`:`features`]
388 * * [`chain_hash`:`chain_hash`]
389 * * [`short_channel_id`:`short_channel_id`]
390 * * [`point`:`node_id_1`]
391 * * [`point`:`node_id_2`]
392 */
add_channel(struct gossmap * map,size_t cannounce_off,bool private)393 static struct gossmap_chan *add_channel(struct gossmap *map,
394 size_t cannounce_off,
395 bool private)
396 {
397 /* Note that first two bytes are message type */
398 const size_t feature_len_off = 2 + (64 + 64 + 64 + 64);
399 size_t feature_len;
400 size_t plus_scid_off;
401 struct node_id node_id[2];
402 struct gossmap_node *n[2];
403 struct gossmap_chan *chan;
404 u32 nidx[2];
405
406 feature_len = map_be16(map, cannounce_off + feature_len_off);
407 plus_scid_off = feature_len_off + 2 + feature_len + 32;
408
409 map_nodeid(map, cannounce_off + plus_scid_off + 8, &node_id[0]);
410 map_nodeid(map, cannounce_off + plus_scid_off + 8 + PUBKEY_CMPR_LEN, &node_id[1]);
411
412 /* We carefully map pointers to indexes, since new_node can move them! */
413 n[0] = gossmap_find_node(map, &node_id[0]);
414 if (n[0])
415 nidx[0] = gossmap_node_idx(map, n[0]);
416 else
417 nidx[0] = new_node(map);
418
419 n[1] = gossmap_find_node(map, &node_id[1]);
420 if (n[1])
421 nidx[1] = gossmap_node_idx(map, n[1]);
422 else
423 nidx[1] = new_node(map);
424
425 chan = new_channel(map, cannounce_off, plus_scid_off, private,
426 nidx[0], nidx[1]);
427
428 /* Now we have a channel, we can add nodes to htable */
429 if (!n[0])
430 nodeidx_htable_add(&map->nodes,
431 node2ptrint(map->node_arr + nidx[0]));
432 if (!n[1])
433 nodeidx_htable_add(&map->nodes,
434 node2ptrint(map->node_arr + nidx[1]));
435
436 return chan;
437 }
438
439 /* BOLT #7:
440 * 1. type: 258 (`channel_update`)
441 * 2. data:
442 * * [`signature`:`signature`]
443 * * [`chain_hash`:`chain_hash`]
444 * * [`short_channel_id`:`short_channel_id`]
445 * * [`u32`:`timestamp`]
446 * * [`byte`:`message_flags`]
447 * * [`byte`:`channel_flags`]
448 * * [`u16`:`cltv_expiry_delta`]
449 * * [`u64`:`htlc_minimum_msat`]
450 * * [`u32`:`fee_base_msat`]
451 * * [`u32`:`fee_proportional_millionths`]
452 * * [`u64`:`htlc_maximum_msat`] (option_channel_htlc_max)
453 */
update_channel(struct gossmap * map,size_t cupdate_off)454 static bool update_channel(struct gossmap *map, size_t cupdate_off)
455 {
456 /* Note that first two bytes are message type */
457 const size_t scid_off = cupdate_off + 2 + (64 + 32);
458 const size_t message_flags_off = scid_off + 8 + 4;
459 const size_t channel_flags_off = message_flags_off + 1;
460 const size_t cltv_expiry_delta_off = channel_flags_off + 1;
461 const size_t htlc_minimum_off = cltv_expiry_delta_off + 2;
462 const size_t fee_base_off = htlc_minimum_off + 8;
463 const size_t fee_prop_off = fee_base_off + 4;
464 const size_t htlc_maximum_off = fee_prop_off + 4;
465 struct short_channel_id scid;
466 struct gossmap_chan *chan;
467 struct half_chan hc;
468 u8 chanflags;
469 bool dumb_values;
470
471 scid.u64 = map_be64(map, scid_off);
472 chan = gossmap_find_chan(map, &scid);
473 if (!chan)
474 errx(1, "update for channel %s not found!",
475 type_to_string(tmpctx, struct short_channel_id, &scid));
476
477 /* We round this *down*, since too-low min is more conservative */
478 hc.htlc_min = u64_to_fp16(map_be64(map, htlc_minimum_off), false);
479 /* I checked my node: 60189 of 62358 channel_update have
480 * htlc_maximum_msat, so we don't bother setting the rest to the
481 * channel size (which we don't even read from the gossip_store, let
482 * alone give up precious bytes to remember) */
483 if (map_u8(map, message_flags_off) & 1)
484 hc.htlc_max
485 = u64_to_fp16(map_be64(map, htlc_maximum_off), true);
486 else
487 hc.htlc_max = 0xFFFF;
488
489 chanflags = map_u8(map, channel_flags_off);
490 hc.enabled = !(chanflags & 2);
491 hc.base_fee = map_be32(map, fee_base_off);
492 hc.proportional_fee = map_be32(map, fee_prop_off);
493 hc.delay = map_be16(map, cltv_expiry_delta_off);
494
495 /* Check they fit: we turn off if not. */
496 if (hc.base_fee != map_be32(map, fee_base_off)
497 || hc.proportional_fee != map_be32(map, fee_prop_off)
498 || hc.delay != map_be16(map, cltv_expiry_delta_off)) {
499 dumb_values = true;
500 hc.htlc_max = 0;
501 hc.enabled = false;
502 } else
503 dumb_values = false;
504
505 /* Preserve this */
506 hc.nodeidx = chan->half[chanflags & 1].nodeidx;
507 chan->half[chanflags & 1] = hc;
508 chan->cupdate_off[chanflags & 1] = cupdate_off;
509
510 return !dumb_values;
511 }
512
remove_channel_by_deletemsg(struct gossmap * map,size_t del_off)513 static void remove_channel_by_deletemsg(struct gossmap *map, size_t del_off)
514 {
515 struct short_channel_id scid;
516 struct gossmap_chan *chan;
517
518 /* They can delete things we don't know about, since they also
519 * get their length marked with the deleted bit */
520 /* Note that first two bytes are message type */
521 scid.u64 = map_be64(map, del_off + 2);
522 chan = gossmap_find_chan(map, &scid);
523 if (!chan)
524 return;
525
526 gossmap_remove_chan(map, chan);
527 }
528
gossmap_chan_scid(const struct gossmap * map,const struct gossmap_chan * c)529 struct short_channel_id gossmap_chan_scid(const struct gossmap *map,
530 const struct gossmap_chan *c)
531 {
532 struct short_channel_id scid;
533 scid.u64 = map_be64(map, c->cann_off + c->plus_scid_off);
534
535 return scid;
536 }
537
538 /* BOLT #7:
539 * 1. type: 257 (`node_announcement`)
540 * 2. data:
541 * * [`signature`:`signature`]
542 * * [`u16`:`flen`]
543 * * [`flen*byte`:`features`]
544 * * [`u32`:`timestamp`]
545 * * [`point`:`node_id`]
546 * * [`3*byte`:`rgb_color`]
547 * * [`32*byte`:`alias`]
548 * * [`u16`:`addrlen`]
549 * * [`addrlen*byte`:`addresses`]
550 */
node_announcement(struct gossmap * map,size_t nann_off)551 static void node_announcement(struct gossmap *map, size_t nann_off)
552 {
553 const size_t feature_len_off = 2 + 64;
554 size_t feature_len;
555 struct gossmap_node *n;
556 struct node_id id;
557
558 feature_len = map_be16(map, nann_off + feature_len_off);
559 map_nodeid(map, nann_off + feature_len_off + 2 + feature_len + 4, &id);
560 n = gossmap_find_node(map, &id);
561 n->nann_off = nann_off;
562 }
563
reopen_store(struct gossmap * map,size_t ended_off)564 static void reopen_store(struct gossmap *map, size_t ended_off)
565 {
566 int fd = open(map->fname, O_RDONLY);
567
568 if (fd < 0)
569 err(1, "Failed to reopen %s", map->fname);
570
571 /* This tells us the equivalent offset in new map */
572 map->map_end = map_be64(map, ended_off + 2);
573
574 close(map->fd);
575 map->fd = fd;
576 gossmap_refresh(map, NULL);
577 }
578
map_catchup(struct gossmap * map,size_t * num_rejected)579 static bool map_catchup(struct gossmap *map, size_t *num_rejected)
580 {
581 size_t reclen;
582 bool changed = false;
583 size_t num_bad = 0;
584
585 for (; map->map_end + sizeof(struct gossip_hdr) < map->map_size;
586 map->map_end += reclen) {
587 struct gossip_hdr ghdr;
588 size_t off;
589 u16 type;
590
591 map_copy(map, map->map_end, &ghdr, sizeof(ghdr));
592 reclen = (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_MASK)
593 + sizeof(ghdr);
594
595 if (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_DELETED_BIT)
596 continue;
597
598 /* Partial write, this can happen. */
599 if (map->map_end + reclen > map->map_size)
600 break;
601
602 off = map->map_end + sizeof(ghdr);
603 type = map_be16(map, off);
604 if (type == WIRE_CHANNEL_ANNOUNCEMENT)
605 add_channel(map, off, false);
606 else if (type == WIRE_GOSSIP_STORE_PRIVATE_CHANNEL)
607 add_channel(map, off + 2 + 8 + 2, true);
608 else if (type == WIRE_CHANNEL_UPDATE)
609 num_bad += !update_channel(map, off);
610 else if (type == WIRE_GOSSIP_STORE_PRIVATE_UPDATE)
611 num_bad += !update_channel(map, off + 2 + 2);
612 else if (type == WIRE_GOSSIP_STORE_DELETE_CHAN)
613 remove_channel_by_deletemsg(map, off);
614 else if (type == WIRE_NODE_ANNOUNCEMENT)
615 node_announcement(map, off);
616 else if (type == WIRE_GOSSIP_STORE_ENDED)
617 reopen_store(map, off);
618 else
619 continue;
620
621 changed = true;
622 }
623
624 if (num_rejected)
625 *num_rejected = num_bad;
626 return changed;
627 }
628
load_gossip_store(struct gossmap * map,size_t * num_rejected)629 static bool load_gossip_store(struct gossmap *map, size_t *num_rejected)
630 {
631 map->fd = open(map->fname, O_RDONLY);
632 if (map->fd < 0)
633 return false;
634
635 map->map_size = lseek(map->fd, 0, SEEK_END);
636 map->local = NULL;
637 /* If this fails, we fall back to read */
638 map->mmap = mmap(NULL, map->map_size, PROT_READ, MAP_SHARED, map->fd, 0);
639 if (map->mmap == MAP_FAILED)
640 map->mmap = NULL;
641
642 if (map_u8(map, 0) != GOSSIP_STORE_VERSION) {
643 close(map->fd);
644 if (map->mmap)
645 munmap(map->mmap, map->map_size);
646 errno = EINVAL;
647 return false;
648 }
649
650 /* Since channel_announcement is ~430 bytes, and channel_update is 136,
651 * node_announcement is 144, and current topology has 35000 channels
652 * and 10000 nodes, let's assume each channel gets about 750 bytes.
653 *
654 * We halve this, since often some records are deleted. */
655 chanidx_htable_init_sized(&map->channels, map->map_size / 750 / 2);
656 nodeidx_htable_init_sized(&map->nodes, map->map_size / 2500 / 2);
657
658 map->chan_arr = tal_arr(map, struct gossmap_chan, map->map_size / 750 / 2 + 1);
659 map->freed_chans = init_chan_arr(map->chan_arr, 0);
660 map->node_arr = tal_arr(map, struct gossmap_node, map->map_size / 2500 / 2 + 1);
661 map->freed_nodes = init_node_arr(map->node_arr, 0);
662
663 map->map_end = 1;
664 map_catchup(map, num_rejected);
665 return true;
666 }
667
destroy_map(struct gossmap * map)668 static void destroy_map(struct gossmap *map)
669 {
670 if (map->mmap)
671 munmap(map->mmap, map->map_size);
672 chanidx_htable_clear(&map->channels);
673 nodeidx_htable_clear(&map->nodes);
674
675 for (size_t i = 0; i < tal_count(map->node_arr); i++)
676 free(map->node_arr[i].chan_idxs);
677 }
678
679 /* Local modifications. We only expect a few, so we use a simple
680 * array. */
681 struct localmod {
682 struct short_channel_id scid;
683 /* If this is an entirely-local channel, here's its offset.
684 * Otherwise, 0xFFFFFFFF. */
685 u32 local_off;
686
687 /* Are updates in either direction set? */
688 bool updates_set[2];
689 /* hc[n] defined if updates_set[n]. */
690 struct half_chan hc[2];
691 /* orig[n] defined if updates_set[n] and local_off == 0xFFFFFFFF */
692 struct half_chan orig[2];
693
694 /* Original update offsets */
695 u32 orig_cupdate_off[2];
696 };
697
698 struct gossmap_localmods {
699 struct localmod *mods;
700 /* This is the local array to be used by the gossmap */
701 u8 *local;
702 };
703
gossmap_localmods_new(const tal_t * ctx)704 struct gossmap_localmods *gossmap_localmods_new(const tal_t *ctx)
705 {
706 struct gossmap_localmods *localmods;
707
708 localmods = tal(ctx, struct gossmap_localmods);
709 localmods->mods = tal_arr(localmods, struct localmod, 0);
710 localmods->local = tal_arr(localmods, u8, 0);
711
712 return localmods;
713 }
714
715 /* Create space at end of local map, return offset it was added at. */
insert_local_space(struct gossmap_localmods * localmods,size_t msglen)716 static size_t insert_local_space(struct gossmap_localmods *localmods,
717 size_t msglen)
718 {
719 size_t oldlen = tal_bytelen(localmods->local);
720
721 tal_resize(&localmods->local, oldlen + msglen);
722 return oldlen;
723 }
724
find_localmod(struct gossmap_localmods * localmods,const struct short_channel_id * scid)725 static struct localmod *find_localmod(struct gossmap_localmods *localmods,
726 const struct short_channel_id *scid)
727 {
728 for (size_t i = 0; i < tal_count(localmods->mods); i++)
729 if (short_channel_id_eq(&localmods->mods[i].scid, scid))
730 return &localmods->mods[i];
731 return NULL;
732 }
733
gossmap_local_addchan(struct gossmap_localmods * localmods,const struct node_id * n1,const struct node_id * n2,const struct short_channel_id * scid,const u8 * features)734 bool gossmap_local_addchan(struct gossmap_localmods *localmods,
735 const struct node_id *n1,
736 const struct node_id *n2,
737 const struct short_channel_id *scid,
738 const u8 *features)
739 {
740 be16 be16;
741 be64 be64;
742 size_t off;
743 struct localmod mod;
744
745 /* Don't create duplicate channels. */
746 if (find_localmod(localmods, scid))
747 return false;
748
749 mod.scid = *scid;
750 mod.updates_set[0] = mod.updates_set[1] = false;
751
752 /* We create fake local channel_announcement. */
753 off = insert_local_space(localmods,
754 2 + 64 * 4 + 2 + tal_bytelen(features)
755 + 32 + 8 + 33 + 33);
756 mod.local_off = off;
757
758 /* Set type to be kosher. */
759 be16 = CPU_TO_BE16(WIRE_CHANNEL_ANNOUNCEMENT);
760 memcpy(localmods->local + off, &be16, sizeof(be16));
761 off += sizeof(be16);
762
763 /* Skip sigs */
764 off += 64 * 4;
765
766 /* Set length and features */
767 be16 = cpu_to_be16(tal_bytelen(features));
768 memcpy(localmods->local + off, &be16, sizeof(be16));
769 off += sizeof(be16);
770 memcpy(localmods->local + off, features, tal_bytelen(features));
771 off += tal_bytelen(features);
772
773 /* Skip chain_hash */
774 off += 32;
775
776 /* Set scid */
777 be64 = be64_to_cpu(scid->u64);
778 memcpy(localmods->local + off, &be64, sizeof(be64));
779 off += sizeof(be64);
780
781 /* set node_ids */
782 memcpy(localmods->local + off, n1->k, sizeof(n1->k));
783 off += sizeof(n1->k);
784 memcpy(localmods->local + off, n2->k, sizeof(n2->k));
785 off += sizeof(n2->k);
786
787 assert(off == tal_bytelen(localmods->local));
788
789 tal_arr_expand(&localmods->mods, mod);
790 return true;
791 };
792
793 /* Insert a local-only channel_update. */
gossmap_local_updatechan(struct gossmap_localmods * localmods,const struct short_channel_id * scid,struct amount_msat htlc_min,struct amount_msat htlc_max,u32 base_fee,u32 proportional_fee,u16 delay,bool enabled,int dir)794 bool gossmap_local_updatechan(struct gossmap_localmods *localmods,
795 const struct short_channel_id *scid,
796 struct amount_msat htlc_min,
797 struct amount_msat htlc_max,
798 u32 base_fee,
799 u32 proportional_fee,
800 u16 delay,
801 bool enabled,
802 int dir)
803 {
804 struct localmod *mod;
805
806 mod = find_localmod(localmods, scid);
807 if (!mod) {
808 /* Create new reference to (presumably) existing channel. */
809 size_t nmods = tal_count(localmods->mods);
810
811 tal_resize(&localmods->mods, nmods + 1);
812 mod = &localmods->mods[nmods];
813 mod->scid = *scid;
814 mod->updates_set[0] = mod->updates_set[1] = false;
815 mod->local_off = 0xFFFFFFFF;
816 }
817
818 assert(dir == 0 || dir == 1);
819 mod->updates_set[dir] = true;
820 mod->hc[dir].enabled = enabled;
821 /* node_idx needs to be set once we're in the gossmap. */
822 mod->hc[dir].htlc_min
823 = u64_to_fp16(htlc_min.millisatoshis, /* Raw: to fp16 */
824 false);
825 mod->hc[dir].htlc_max
826 = u64_to_fp16(htlc_max.millisatoshis, /* Raw: to fp16 */
827 true);
828 mod->hc[dir].base_fee = base_fee;
829 mod->hc[dir].proportional_fee = proportional_fee;
830 mod->hc[dir].delay = delay;
831
832 /* Check they fit */
833 if (mod->hc[dir].base_fee != base_fee
834 || mod->hc[dir].proportional_fee != proportional_fee
835 || mod->hc[dir].delay != delay)
836 return false;
837 return true;
838 }
839
840 /* Apply localmods to this map */
gossmap_apply_localmods(struct gossmap * map,struct gossmap_localmods * localmods)841 void gossmap_apply_localmods(struct gossmap *map,
842 struct gossmap_localmods *localmods)
843 {
844 size_t n = tal_count(localmods->mods);
845
846 assert(!map->local);
847 map->local = localmods->local;
848
849 for (size_t i = 0; i < n; i++) {
850 struct localmod *mod = &localmods->mods[i];
851 struct gossmap_chan *chan;
852
853 /* Find gossmap entry which this applies to. */
854 chan = gossmap_find_chan(map, &mod->scid);
855 /* If it doesn't exist, are we supposed to create a local one? */
856 if (!chan) {
857 if (mod->local_off == 0xFFFFFFFF)
858 continue;
859
860 /* Create new channel, pointing into local. */
861 chan = add_channel(map, map->map_size + mod->local_off,
862 true);
863 }
864
865 /* Save old, overwrite (keep nodeidx) */
866 for (size_t h = 0; h < 2; h++) {
867 if (!mod->updates_set[h])
868 continue;
869 mod->orig[h] = chan->half[h];
870 mod->orig_cupdate_off[h] = chan->cupdate_off[h];
871 chan->half[h] = mod->hc[h];
872 chan->half[h].nodeidx = mod->orig[h].nodeidx;
873 chan->cupdate_off[h] = 0xFFFFFFFF;
874 }
875 }
876 }
877
gossmap_remove_localmods(struct gossmap * map,const struct gossmap_localmods * localmods)878 void gossmap_remove_localmods(struct gossmap *map,
879 const struct gossmap_localmods *localmods)
880 {
881 size_t n = tal_count(localmods->mods);
882
883 assert(map->local == localmods->local);
884
885 for (size_t i = 0; i < n; i++) {
886 const struct localmod *mod = &localmods->mods[i];
887 struct gossmap_chan *chan = gossmap_find_chan(map, &mod->scid);
888
889 /* If that's a local channel, remove it now. */
890 if (chan->cann_off >= map->map_size) {
891 gossmap_remove_chan(map, chan);
892 } else {
893 /* Restore (keep nodeidx). */
894 for (size_t h = 0; h < 2; h++) {
895 u32 nodeidx;
896 if (!mod->updates_set[h])
897 continue;
898
899 nodeidx = chan->half[h].nodeidx;
900 chan->half[h] = mod->orig[h];
901 chan->half[h].nodeidx = nodeidx;
902 chan->cupdate_off[h] = mod->orig_cupdate_off[h];
903 }
904 }
905 }
906 map->local = NULL;
907 }
908
gossmap_refresh(struct gossmap * map,size_t * num_rejected)909 bool gossmap_refresh(struct gossmap *map, size_t *num_rejected)
910 {
911 off_t len;
912
913 /* You must remove local updates before this. */
914 assert(!map->local);
915
916 /* If file has gotten larger, try rereading */
917 len = lseek(map->fd, 0, SEEK_END);
918 if (len == map->map_size)
919 return false;
920
921 if (map->mmap)
922 munmap(map->mmap, map->map_size);
923 map->map_size = len;
924 map->mmap = mmap(NULL, map->map_size, PROT_READ, MAP_SHARED, map->fd, 0);
925 if (map->mmap == MAP_FAILED)
926 map->mmap = NULL;
927 return map_catchup(map, num_rejected);
928 }
929
gossmap_load(const tal_t * ctx,const char * filename,size_t * num_channel_updates_rejected)930 struct gossmap *gossmap_load(const tal_t *ctx, const char *filename,
931 size_t *num_channel_updates_rejected)
932 {
933 map = tal(ctx, struct gossmap);
934 map->fname = tal_strdup(map, filename);
935 if (load_gossip_store(map, num_channel_updates_rejected))
936 tal_add_destructor(map, destroy_map);
937 else
938 map = tal_free(map);
939 return map;
940 }
941
gossmap_node_get_id(const struct gossmap * map,const struct gossmap_node * node,struct node_id * id)942 void gossmap_node_get_id(const struct gossmap *map,
943 const struct gossmap_node *node,
944 struct node_id *id)
945 {
946 /* We extract nodeid from first channel. */
947 int dir;
948 struct gossmap_chan *c = gossmap_nth_chan(map, node, 0, &dir);
949
950 map_nodeid(map, c->cann_off + c->plus_scid_off
951 + 8 + PUBKEY_CMPR_LEN*dir, id);
952 }
953
gossmap_chan_get_capacity(const struct gossmap * map,const struct gossmap_chan * c,struct amount_sat * amount)954 bool gossmap_chan_get_capacity(const struct gossmap *map,
955 const struct gossmap_chan *c,
956 struct amount_sat *amount)
957 {
958 struct gossip_hdr ghdr;
959 size_t off;
960 u16 type;
961
962 /* For private, we need to go back WIRE_GOSSIP_STORE_PRIVATE_CHANNEL,
963 * which is 8 (satoshis) + 2 (len) */
964 if (c->private) {
965 *amount = amount_sat(map_be64(map, c->cann_off - 8 - 2));
966 return true;
967 }
968
969 /* Skip over this record to next; expect a gossip_store_channel_amount */
970 off = c->cann_off - sizeof(ghdr);
971 map_copy(map, off, &ghdr, sizeof(ghdr));
972 off += sizeof(ghdr) + (be32_to_cpu(ghdr.len) & GOSSIP_STORE_LEN_MASK);
973
974 /* Partial write, this can happen. */
975 if (off + sizeof(ghdr) + 2 > map->map_size)
976 return false;
977
978 /* Get type of next field. */
979 type = map_be16(map, off + sizeof(ghdr));
980 if (type != WIRE_GOSSIP_STORE_CHANNEL_AMOUNT)
981 return false;
982
983 *amount = amount_sat(map_be64(map, off + sizeof(ghdr) + sizeof(be16)));
984 return true;
985 }
986
gossmap_nth_chan(const struct gossmap * map,const struct gossmap_node * node,u32 n,int * which_half)987 struct gossmap_chan *gossmap_nth_chan(const struct gossmap *map,
988 const struct gossmap_node *node,
989 u32 n,
990 int *which_half)
991 {
992 struct gossmap_chan *chan;
993
994 assert(n < node->num_chans);
995 assert(node->chan_idxs[n] < tal_count(map->chan_arr));
996 chan = map->chan_arr + node->chan_idxs[n];
997
998 if (which_half) {
999 if (chan->half[0].nodeidx == gossmap_node_idx(map, node))
1000 *which_half = 0;
1001 else {
1002 assert(chan->half[1].nodeidx == gossmap_node_idx(map, node));
1003 *which_half = 1;
1004 }
1005 }
1006 return chan;
1007 }
1008
gossmap_nth_node(const struct gossmap * map,const struct gossmap_chan * chan,int n)1009 struct gossmap_node *gossmap_nth_node(const struct gossmap *map,
1010 const struct gossmap_chan *chan,
1011 int n)
1012 {
1013 assert(n == 0 || n == 1);
1014
1015 return map->node_arr + chan->half[n].nodeidx;
1016 }
1017
gossmap_num_nodes(const struct gossmap * map)1018 size_t gossmap_num_nodes(const struct gossmap *map)
1019 {
1020 return nodeidx_htable_count(&map->nodes);
1021 }
1022
node_iter(const struct gossmap * map,size_t start)1023 static struct gossmap_node *node_iter(const struct gossmap *map, size_t start)
1024 {
1025 for (size_t i = start; i < tal_count(map->node_arr); i++) {
1026 if (map->node_arr[i].chan_idxs != NULL)
1027 return &map->node_arr[i];
1028 }
1029 return NULL;
1030 }
1031
gossmap_first_node(const struct gossmap * map)1032 struct gossmap_node *gossmap_first_node(const struct gossmap *map)
1033 {
1034 return node_iter(map, 0);
1035 }
1036
gossmap_next_node(const struct gossmap * map,const struct gossmap_node * prev)1037 struct gossmap_node *gossmap_next_node(const struct gossmap *map,
1038 const struct gossmap_node *prev)
1039 {
1040 return node_iter(map, prev - map->node_arr + 1);
1041 }
1042
gossmap_num_chans(const struct gossmap * map)1043 size_t gossmap_num_chans(const struct gossmap *map)
1044 {
1045 return chanidx_htable_count(&map->channels);
1046 }
1047
chan_iter(const struct gossmap * map,size_t start)1048 static struct gossmap_chan *chan_iter(const struct gossmap *map, size_t start)
1049 {
1050 for (size_t i = start; i < tal_count(map->chan_arr); i++) {
1051 if (map->chan_arr[i].plus_scid_off != 0)
1052 return &map->chan_arr[i];
1053 }
1054 return NULL;
1055 }
1056
gossmap_first_chan(const struct gossmap * map)1057 struct gossmap_chan *gossmap_first_chan(const struct gossmap *map)
1058 {
1059 return chan_iter(map, 0);
1060 }
1061
gossmap_next_chan(const struct gossmap * map,struct gossmap_chan * prev)1062 struct gossmap_chan *gossmap_next_chan(const struct gossmap *map,
1063 struct gossmap_chan *prev)
1064 {
1065 return chan_iter(map, prev - map->chan_arr + 1);
1066 }
1067
gossmap_chan_capacity(const struct gossmap_chan * chan,int direction,struct amount_msat amount)1068 bool gossmap_chan_capacity(const struct gossmap_chan *chan,
1069 int direction,
1070 struct amount_msat amount)
1071 {
1072 if (amount_msat_less_fp16(amount, chan->half[direction].htlc_min))
1073 return false;
1074
1075 if (amount_msat_greater_fp16(amount, chan->half[direction].htlc_max))
1076 return false;
1077
1078 return true;
1079 }
1080
1081 /* Get the announcement msg which created this chan */
gossmap_chan_get_announce(const tal_t * ctx,const struct gossmap * map,const struct gossmap_chan * c)1082 u8 *gossmap_chan_get_announce(const tal_t *ctx,
1083 const struct gossmap *map,
1084 const struct gossmap_chan *c)
1085 {
1086 u32 len;
1087 u8 *msg;
1088 u32 pre_off;
1089
1090 /* We need to go back to struct gossip_hdr to get len */
1091 if (c->private)
1092 pre_off = 2 + 8 + 2 + sizeof(struct gossip_hdr);
1093 else
1094 pre_off = sizeof(struct gossip_hdr);
1095 len = (map_be32(map, c->cann_off - pre_off) & GOSSIP_STORE_LEN_MASK);
1096
1097 msg = tal_arr(ctx, u8, len);
1098 map_copy(map, c->cann_off, msg, len);
1099 return msg;
1100 }
1101
1102 /* Get the announcement msg (if any) for this node. */
gossmap_node_get_announce(const tal_t * ctx,const struct gossmap * map,const struct gossmap_node * n)1103 u8 *gossmap_node_get_announce(const tal_t *ctx,
1104 const struct gossmap *map,
1105 const struct gossmap_node *n)
1106 {
1107 u32 len;
1108 u8 *msg;
1109
1110 if (n->nann_off == 0)
1111 return NULL;
1112
1113 len = (map_be32(map, n->nann_off - sizeof(struct gossip_hdr))
1114 & GOSSIP_STORE_LEN_MASK);
1115 msg = tal_arr(ctx, u8, len);
1116
1117 map_copy(map, n->nann_off, msg, len);
1118 return msg;
1119 }
1120
1121 /* BOLT #7:
1122 * 1. type: 256 (`channel_announcement`)
1123 * 2. data:
1124 * * [`signature`:`node_signature_1`]
1125 * * [`signature`:`node_signature_2`]
1126 * * [`signature`:`bitcoin_signature_1`]
1127 * * [`signature`:`bitcoin_signature_2`]
1128 * * [`u16`:`len`]
1129 * * [`len*byte`:`features`]
1130 * * [`chain_hash`:`chain_hash`]
1131 * * [`short_channel_id`:`short_channel_id`]
1132 * * [`point`:`node_id_1`]
1133 * * [`point`:`node_id_2`]
1134 */
gossmap_chan_get_feature(const struct gossmap * map,const struct gossmap_chan * c,int fbit)1135 int gossmap_chan_get_feature(const struct gossmap *map,
1136 const struct gossmap_chan *c,
1137 int fbit)
1138 {
1139 /* Note that first two bytes are message type */
1140 const size_t feature_len_off = 2 + (64 + 64 + 64 + 64);
1141 size_t feature_len;
1142
1143 feature_len = map_be16(map, c->cann_off + feature_len_off);
1144
1145 return map_feature_test(map, COMPULSORY_FEATURE(fbit),
1146 c->cann_off + feature_len_off + 2, feature_len);
1147 }
1148
gossmap_chan_get_features(const tal_t * ctx,const struct gossmap * map,const struct gossmap_chan * c)1149 u8 *gossmap_chan_get_features(const tal_t *ctx,
1150 const struct gossmap *map,
1151 const struct gossmap_chan *c)
1152 {
1153 u8 *ret;
1154 /* Note that first two bytes are message type */
1155 const size_t feature_len_off = 2 + (64 + 64 + 64 + 64);
1156 size_t feature_len;
1157
1158 feature_len = map_be16(map, c->cann_off + feature_len_off);
1159 ret = tal_arr(ctx, u8, feature_len);
1160
1161 map_copy(map, c->cann_off + feature_len_off + 2, ret, feature_len);
1162 return ret;
1163 }
1164
1165 /* BOLT #7:
1166 * 1. type: 258 (`channel_update`)
1167 * 2. data:
1168 * * [`signature`:`signature`]
1169 * * [`chain_hash`:`chain_hash`]
1170 * * [`short_channel_id`:`short_channel_id`]
1171 * * [`u32`:`timestamp`]
1172 * * [`byte`:`message_flags`]
1173 * * [`byte`:`channel_flags`]
1174 * * [`u16`:`cltv_expiry_delta`]
1175 * * [`u64`:`htlc_minimum_msat`]
1176 * * [`u32`:`fee_base_msat`]
1177 * * [`u32`:`fee_proportional_millionths`]
1178 * * [`u64`:`htlc_maximum_msat`] (option_channel_htlc_max)
1179 */
gossmap_chan_get_update_details(const struct gossmap * map,const struct gossmap_chan * chan,int dir,u32 * timestamp,u8 * message_flags,u8 * channel_flags,u32 * fee_base_msat,u32 * fee_proportional_millionths,struct amount_msat * htlc_minimum_msat,struct amount_msat * htlc_maximum_msat)1180 void gossmap_chan_get_update_details(const struct gossmap *map,
1181 const struct gossmap_chan *chan,
1182 int dir,
1183 u32 *timestamp,
1184 u8 *message_flags,
1185 u8 *channel_flags,
1186 u32 *fee_base_msat,
1187 u32 *fee_proportional_millionths,
1188 struct amount_msat *htlc_minimum_msat,
1189 /* iff message_flags & 1 */
1190 struct amount_msat *htlc_maximum_msat)
1191 {
1192 /* Note that first two bytes are message type */
1193 const size_t scid_off = chan->cupdate_off[dir] + 2 + (64 + 32);
1194 const size_t timestamp_off = scid_off + 8;
1195 const size_t message_flags_off = timestamp_off + 4;
1196 const size_t channel_flags_off = message_flags_off + 1;
1197 const size_t cltv_expiry_delta_off = channel_flags_off + 1;
1198 const size_t htlc_minimum_off = cltv_expiry_delta_off + 2;
1199 const size_t fee_base_off = htlc_minimum_off + 8;
1200 const size_t fee_prop_off = fee_base_off + 4;
1201 const size_t htlc_maximum_off = fee_prop_off + 4;
1202 u8 mflags;
1203
1204 assert(gossmap_chan_set(chan, dir));
1205
1206 if (timestamp)
1207 *timestamp = map_be32(map, timestamp_off);
1208 /* We need this (below), even if they don't want it */
1209 mflags = map_u8(map, message_flags_off);
1210 if (message_flags)
1211 *message_flags = mflags;
1212 if (channel_flags)
1213 *channel_flags = map_u8(map, channel_flags_off);
1214 if (fee_base_msat)
1215 *fee_base_msat = map_be32(map, fee_base_off);
1216 if (fee_proportional_millionths)
1217 *fee_proportional_millionths = map_be32(map, fee_prop_off);
1218 if (htlc_minimum_msat)
1219 *htlc_minimum_msat
1220 = amount_msat(map_be64(map, htlc_minimum_off));
1221 if (htlc_maximum_msat && (mflags & 1))
1222 *htlc_maximum_msat
1223 = amount_msat(map_be64(map, htlc_maximum_off));
1224 }
1225
1226 /* BOLT #7:
1227 * 1. type: 257 (`node_announcement`)
1228 * 2. data:
1229 * * [`signature`:`signature`]
1230 * * [`u16`:`flen`]
1231 * * [`flen*byte`:`features`]
1232 * * [`u32`:`timestamp`]
1233 * * [`point`:`node_id`]
1234 * * [`3*byte`:`rgb_color`]
1235 * * [`32*byte`:`alias`]
1236 * * [`u16`:`addrlen`]
1237 * * [`addrlen*byte`:`addresses`]
1238 */
gossmap_node_get_feature(const struct gossmap * map,const struct gossmap_node * n,int fbit)1239 int gossmap_node_get_feature(const struct gossmap *map,
1240 const struct gossmap_node *n,
1241 int fbit)
1242 {
1243 const size_t feature_len_off = 2 + 64;
1244 size_t feature_len;
1245
1246 if (n->nann_off == 0)
1247 return -1;
1248
1249 feature_len = map_be16(map, n->nann_off + feature_len_off);
1250
1251 return map_feature_test(map, COMPULSORY_FEATURE(fbit),
1252 n->nann_off + feature_len_off + 2, feature_len);
1253 }
1254
1255 /* There are two 33-byte pubkeys possible: choose the one which appears
1256 * in the graph (otherwise payment will fail anyway). */
gossmap_guess_node_id(const struct gossmap * map,const struct point32 * point32,struct node_id * id)1257 void gossmap_guess_node_id(const struct gossmap *map,
1258 const struct point32 *point32,
1259 struct node_id *id)
1260 {
1261 id->k[0] = SECP256K1_TAG_PUBKEY_EVEN;
1262 secp256k1_xonly_pubkey_serialize(secp256k1_ctx,
1263 id->k + 1,
1264 &point32->pubkey);
1265
1266 /* If we don't find this, let's assume it's odd. */
1267 if (!gossmap_find_node(map, id))
1268 id->k[0] = SECP256K1_TAG_PUBKEY_ODD;
1269 }
1270