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