1 #ifndef LIGHTNING_COMMON_GOSSMAP_H
2 #define LIGHTNING_COMMON_GOSSMAP_H
3 #include "config.h"
4 #include <bitcoin/short_channel_id.h>
5 #include <ccan/take/take.h>
6 #include <ccan/typesafe_cb/typesafe_cb.h>
7 #include <common/amount.h>
8 #include <common/fp16.h>
9
10 struct node_id;
11 struct point32;
12
13 struct gossmap_node {
14 /* Offset in memory map for node_announce, or 0. */
15 u32 nann_off;
16 u32 num_chans;
17 u32 *chan_idxs;
18 };
19
20 struct gossmap_chan {
21 u32 cann_off;
22 u32 private: 1;
23 /* Technically redundant, but we have a hole anyway: from cann_off */
24 u32 plus_scid_off: 31;
25 /* Offsets of cupdates (0 if missing). Logically inside half_chan,
26 * but that would add padding. */
27 u32 cupdate_off[2];
28 /* two nodes we connect (lesser idx first) */
29 struct half_chan {
30 /* Top bit indicates it's enabled */
31 u32 enabled: 1;
32 u32 nodeidx : 31;
33 fp16_t htlc_min, htlc_max;
34
35 /* millisatoshi. */
36 u64 base_fee : 24;
37 /* millionths */
38 u64 proportional_fee : 20;
39 /* Delay for HTLC in blocks. */
40 u64 delay : 20;
41 } half[2];
42 };
43
44 /* If num_channel_updates_rejected is not NULL, indicates how many channels we
45 * marked inactive because their values were too high to be represented. */
46 struct gossmap *gossmap_load(const tal_t *ctx, const char *filename,
47 size_t *num_channel_updates_rejected);
48
49 /* Call this before using to ensure it's up-to-date. Returns true if something
50 * was updated. Note: this can scramble node and chan indexes! */
51 bool gossmap_refresh(struct gossmap *map, size_t *num_channel_updates_rejected);
52
53 /* Local modifications. */
54 struct gossmap_localmods *gossmap_localmods_new(const tal_t *ctx);
55
56 /* Create a local-only channel; if this conflicts with a real channel when added,
57 * that will be used instead.
58 * Returns false (and does nothing) if scid was already in localmods.
59 */
60 bool gossmap_local_addchan(struct gossmap_localmods *localmods,
61 const struct node_id *n1,
62 const struct node_id *n2,
63 const struct short_channel_id *scid,
64 const u8 *features)
65 NON_NULL_ARGS(1,2,3,4);
66
67 /* Create a local-only channel_update: can apply to lcoal-only or
68 * normal channels. Returns false if amounts don't fit in our
69 * internal representation (implies channel unusable anyway). */
70 bool gossmap_local_updatechan(struct gossmap_localmods *localmods,
71 const struct short_channel_id *scid,
72 struct amount_msat htlc_min,
73 struct amount_msat htlc_max,
74 u32 base_fee,
75 u32 proportional_fee,
76 u16 delay,
77 bool enabled,
78 int dir)
79 NO_NULL_ARGS;
80
81 /* Apply localmods to this map */
82 void gossmap_apply_localmods(struct gossmap *map,
83 struct gossmap_localmods *localmods);
84
85 /* Remove localmods from this map */
86 void gossmap_remove_localmods(struct gossmap *map,
87 const struct gossmap_localmods *localmods);
88
89 /* Each channel has a unique (low) index. */
90 u32 gossmap_node_idx(const struct gossmap *map, const struct gossmap_node *node);
91 u32 gossmap_chan_idx(const struct gossmap *map, const struct gossmap_chan *chan);
92
93 /* Every node_idx/chan_idx will be < these.
94 * These values can change across calls to gossmap_check. */
95 u32 gossmap_max_node_idx(const struct gossmap *map);
96 u32 gossmap_max_chan_idx(const struct gossmap *map);
97
98 /* Find node with this node_id */
99 struct gossmap_node *gossmap_find_node(const struct gossmap *map,
100 const struct node_id *id);
101 /* Find chan with this short_channel_id */
102 struct gossmap_chan *gossmap_find_chan(const struct gossmap *map,
103 const struct short_channel_id *scid);
104
105 /* Get the short_channel_id of this chan */
106 struct short_channel_id gossmap_chan_scid(const struct gossmap *map,
107 const struct gossmap_chan *c);
108
109 /* Given a struct node, get the node_id */
110 void gossmap_node_get_id(const struct gossmap *map,
111 const struct gossmap_node *node,
112 struct node_id *id);
113
114 /* Do we have any values for this halfchannel ? */
gossmap_chan_set(const struct gossmap_chan * chan,int dir)115 static inline bool gossmap_chan_set(const struct gossmap_chan *chan, int dir)
116 {
117 return chan->cupdate_off[dir] != 0;
118 }
119
120 /* Return capacity if it's known (fails only on race condition) */
121 bool gossmap_chan_get_capacity(const struct gossmap *map,
122 const struct gossmap_chan *c,
123 struct amount_sat *amount);
124
125 /* Get the announcement msg which created this chan */
126 u8 *gossmap_chan_get_announce(const tal_t *ctx,
127 const struct gossmap *map,
128 const struct gossmap_chan *c);
129
130 /* Get the announcement msg (if any) for this node. */
131 u8 *gossmap_node_get_announce(const tal_t *ctx,
132 const struct gossmap *map,
133 const struct gossmap_node *n);
134
135 /* Return the feature bit (odd or even), or -1 if neither. */
136 int gossmap_chan_get_feature(const struct gossmap *map,
137 const struct gossmap_chan *c,
138 int fbit);
139
140 /* Return the feature bitmap */
141 u8 *gossmap_chan_get_features(const tal_t *ctx,
142 const struct gossmap *map,
143 const struct gossmap_chan *c);
144
145 /* Return the feature bit (odd or even), or -1 if neither (or no announcement) */
146 int gossmap_node_get_feature(const struct gossmap *map,
147 const struct gossmap_node *n,
148 int fbit);
149
150 /* Returns details from channel_update (must be gossmap_chan_set, and
151 * does not work for local_updatechan! */
152 void gossmap_chan_get_update_details(const struct gossmap *map,
153 const struct gossmap_chan *chan,
154 int dir,
155 u32 *timestamp,
156 u8 *message_flags,
157 u8 *channel_flags,
158 u32 *fee_base_msat,
159 u32 *fee_proportional_millionths,
160 struct amount_msat *htlc_minimum_msat,
161 /* iff message_flags & 1 */
162 struct amount_msat *htlc_maximum_msat);
163
164 /* Given a struct node, get the nth channel, and tell us if we're half[0/1].
165 * n must be less than node->num_chans */
166 struct gossmap_chan *gossmap_nth_chan(const struct gossmap *map,
167 const struct gossmap_node *node,
168 u32 n,
169 int *which_half);
170
171 /* Given a struct chan, get the nth node, where n is 0 or 1. */
172 struct gossmap_node *gossmap_nth_node(const struct gossmap *map,
173 const struct gossmap_chan *chan,
174 int n);
175
176 /* Can this channel send this amount? */
177 bool gossmap_chan_capacity(const struct gossmap_chan *chan,
178 int direction,
179 struct amount_msat amount);
180
181 /* Remove a channel from the map (warning! realloc can move gossmap_chan
182 * and gossmap_node ptrs!) */
183 void gossmap_remove_chan(struct gossmap *map, struct gossmap_chan *chan);
184
185 /* Remove node (by removing all its channels) */
186 void gossmap_remove_node(struct gossmap *map, struct gossmap_node *node);
187
188 /* Unsorted iterate through (do not add/remove channels or nodes!) */
189 size_t gossmap_num_nodes(const struct gossmap *map);
190
191 struct gossmap_node *gossmap_first_node(const struct gossmap *map);
192 struct gossmap_node *gossmap_next_node(const struct gossmap *map,
193 const struct gossmap_node *prev);
194
195 /* Unsorted iterate through (do not add/remove channels or nodes!) */
196 size_t gossmap_num_chans(const struct gossmap *map);
197
198 struct gossmap_chan *gossmap_first_chan(const struct gossmap *map);
199 struct gossmap_chan *gossmap_next_chan(const struct gossmap *map,
200 struct gossmap_chan *prev);
201
202 /* Each x-only pubkey has two possible values: we can figure out which by
203 * examining the gossmap. */
204 void gossmap_guess_node_id(const struct gossmap *map,
205 const struct point32 *point32,
206 struct node_id *id);
207
208 #endif /* LIGHTNING_COMMON_GOSSMAP_H */
209