BOLT #7: * 1. type: 256 (`channel_announcement`) * 2. data: * * [`signature`:`node_signature_1`] * * [`signature`:`node_signature_2`] * * [`signature`:`bitcoin_signature_1`] * * [`signature`:`bitcoin_signature_2`] * * [`u16`:`len`] * * [`len*byte`:`features`] * * [`chain_hash`:`chain_hash`] * * [`short_channel_id`:`short_channel_id`] * * [`point`:`nod
| 449 | * * [`point`:`node_id_2`] |
| 450 | */ |
| 451 | static struct gossmap_chan *add_channel(struct gossmap *map, |
| 452 | u64 cannounce_off, |
| 453 | size_t msglen, |
| 454 | bool *redundant) |
| 455 | { |
| 456 | /* Note that first two bytes are message type */ |
| 457 | const u64 feature_len_off = 2 + (64 + 64 + 64 + 64); |
| 458 | size_t feature_len; |
| 459 | u64 plus_scid_off; |
| 460 | struct short_channel_id scid; |
| 461 | struct node_id node_id[2]; |
| 462 | struct gossmap_node *n[2]; |
| 463 | struct gossmap_chan *chan; |
| 464 | u32 nidx[2]; |
| 465 | |
| 466 | feature_len = map_be16(map, cannounce_off + feature_len_off); |
| 467 | plus_scid_off = feature_len_off + 2 + feature_len + 32; |
| 468 | |
| 469 | map_nodeid(map, cannounce_off + plus_scid_off + 8, &node_id[0]); |
| 470 | map_nodeid(map, cannounce_off + plus_scid_off + 8 + PUBKEY_CMPR_LEN, &node_id[1]); |
| 471 | |
| 472 | if (redundant) |
| 473 | *redundant = false; |
| 474 | |
| 475 | /* We should not get duplicates. */ |
| 476 | scid.u64 = map_be64(map, cannounce_off + plus_scid_off); |
| 477 | chan = gossmap_find_chan(map, &scid); |
| 478 | if (chan) { |
| 479 | map->logcb(map->cbarg, LOG_BROKEN, |
| 480 | "gossmap: redundant channel_announce for %s, offsets %"PRIu64" and %"PRIu64"!", |
| 481 | fmt_short_channel_id(tmpctx, scid), |
| 482 | chan->cann_off, cannounce_off); |
| 483 | if (redundant) |
| 484 | *redundant = true; |
| 485 | return chan; |
| 486 | } |
| 487 | |
| 488 | /* gossipd writes WIRE_GOSSIP_STORE_CHANNEL_AMOUNT after this, |
| 489 | * so ignore channel_announcement until that appears */ |
| 490 | if (msglen |
| 491 | && (map->map_size < cannounce_off + msglen + sizeof(struct gossip_hdr) + sizeof(u16) + sizeof(u64))) |
| 492 | return NULL; |
| 493 | |
| 494 | /* We carefully map pointers to indexes, since new_node can move them! */ |
| 495 | n[0] = gossmap_find_node(map, &node_id[0]); |
| 496 | if (n[0]) |
| 497 | nidx[0] = gossmap_node_idx(map, n[0]); |
| 498 | else |
| 499 | nidx[0] = new_node(map); |
| 500 | |
| 501 | n[1] = gossmap_find_node(map, &node_id[1]); |
| 502 | if (n[1]) |
| 503 | nidx[1] = gossmap_node_idx(map, n[1]); |
| 504 | else |
| 505 | nidx[1] = new_node(map); |
| 506 | |
| 507 | chan = new_channel(map, cannounce_off, plus_scid_off, |
| 508 | nidx[0], nidx[1]); |
no test coverage detected