forked from ElementsProject/lightning
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrouting.h
302 lines (242 loc) · 8.87 KB
/
routing.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
#ifndef LIGHTNING_GOSSIPD_ROUTING_H
#define LIGHTNING_GOSSIPD_ROUTING_H
#include "config.h"
#include <bitcoin/pubkey.h>
#include <ccan/crypto/siphash24/siphash24.h>
#include <ccan/htable/htable_type.h>
#include <ccan/time/time.h>
#include <gossipd/broadcast.h>
#include <gossipd/gossip_store.h>
#include <wire/gen_onion_wire.h>
#include <wire/wire.h>
#define ROUTING_MAX_HOPS 20
#define ROUTING_FLAGS_DISABLED 2
struct half_chan {
/* millisatoshi. */
u32 base_fee;
/* millionths */
u32 proportional_fee;
/* Delay for HTLC in blocks.*/
u32 delay;
/* Is this connection active? */
bool active;
s64 last_timestamp;
/* Minimum number of msatoshi in an HTLC */
u32 htlc_minimum_msat;
/* Flags as specified by the `channel_update`s, among other
* things indicated direction wrt the `channel_id` */
u16 flags;
/* Cached `channel_update` we might forward to new peers (or 0) */
u64 channel_update_msgidx;
/* If greater than current time, this connection should not
* be used for routing. */
time_t unroutable_until;
};
struct chan {
struct short_channel_id scid;
u8 *txout_script;
/*
* half[0]->src == nodes[0] half[0]->dst == nodes[1]
* half[1]->src == nodes[1] half[1]->dst == nodes[0]
*/
struct half_chan half[2];
/* node[0].id < node[1].id */
struct node *nodes[2];
/* Cached `channel_announcement` we might forward to new peers (or 0) */
u64 channel_announce_msgidx;
/* Is this a public channel, or was it only added locally? */
bool public;
u64 satoshis;
};
struct node {
struct pubkey id;
/* -1 means never; other fields undefined */
s64 last_timestamp;
/* IP/Hostname and port of this node (may be NULL) */
struct wireaddr *addresses;
/* Channels connecting us to other nodes */
struct chan **chans;
/* Temporary data for routefinding. */
struct {
/* Total to get to here from target. */
u64 total;
/* Total risk premium of this route. */
u64 risk;
/* Where that came from. */
struct chan *prev;
} bfg[ROUTING_MAX_HOPS+1];
/* UTF-8 encoded alias as tal_arr, not zero terminated */
u8 *alias;
/* Color to be used when displaying the name */
u8 rgb_color[3];
/* Cached `node_announcement` we might forward to new peers (or 0). */
u64 node_announce_msgidx;
};
const secp256k1_pubkey *node_map_keyof_node(const struct node *n);
size_t node_map_hash_key(const secp256k1_pubkey *key);
bool node_map_node_eq(const struct node *n, const secp256k1_pubkey *key);
HTABLE_DEFINE_TYPE(struct node, node_map_keyof_node, node_map_hash_key, node_map_node_eq, node_map);
struct pending_node_map;
struct pending_cannouncement;
/* If the two nodes[] are id1 and id2, which index would id1 be? */
static inline int pubkey_idx(const struct pubkey *id1, const struct pubkey *id2)
{
return pubkey_cmp(id1, id2) > 0;
}
/* Fast versions: if you know n is one end of the channel */
static inline struct node *other_node(const struct node *n, struct chan *chan)
{
int idx = (chan->nodes[1] == n);
assert(chan->nodes[0] == n || chan->nodes[1] == n);
return chan->nodes[!idx];
}
/* If you know n is one end of the channel, get connection src == n */
static inline struct half_chan *half_chan_from(const struct node *n,
struct chan *chan)
{
int idx = (chan->nodes[1] == n);
assert(chan->nodes[0] == n || chan->nodes[1] == n);
return &chan->half[idx];
}
/* If you know n is one end of the channel, get index dst == n */
static inline int half_chan_to(const struct node *n, struct chan *chan)
{
int idx = (chan->nodes[1] == n);
assert(chan->nodes[0] == n || chan->nodes[1] == n);
return !idx;
}
struct routing_state {
/* All known nodes. */
struct node_map *nodes;
/* node_announcements which are waiting on pending_cannouncement */
struct pending_node_map *pending_node_map;
/* FIXME: Make this a htable! */
/* channel_announcement which are pending short_channel_id lookup */
struct list_head pending_cannouncement;
struct broadcast_state *broadcasts;
struct bitcoin_blkid chain_hash;
/* Our own ID so we can identify local channels */
struct pubkey local_id;
/* How old does a channel have to be before we prune it? */
u32 prune_timeout;
/* Store for processed messages that we might want to remember across
* restarts */
struct gossip_store *store;
/* A map of channels indexed by short_channel_ids */
UINTMAP(struct chan *) chanmap;
};
static inline struct chan *
get_channel(const struct routing_state *rstate,
const struct short_channel_id *scid)
{
return uintmap_get(&rstate->chanmap, scid->u64);
}
struct route_hop {
struct short_channel_id channel_id;
struct pubkey nodeid;
u64 amount;
u32 delay;
};
struct routing_state *new_routing_state(const tal_t *ctx,
const struct bitcoin_blkid *chain_hash,
const struct pubkey *local_id,
u32 prune_timeout);
struct chan *new_chan(struct routing_state *rstate,
const struct short_channel_id *scid,
const struct pubkey *id1,
const struct pubkey *id2);
/* Handlers for incoming messages */
/**
* handle_channel_announcement -- Check channel announcement is valid
*
* Returns error message if we should fail channel. Make *scid non-NULL
* (for checking) if we extracted a short_channel_id, otherwise ignore.
*/
u8 *handle_channel_announcement(struct routing_state *rstate,
const u8 *announce TAKES,
const struct short_channel_id **scid);
/**
* handle_pending_cannouncement -- handle channel_announce once we've
* completed short_channel_id lookup.
*
* Returns true if the channel was new and is local. This means that
* if we haven't sent a node_announcement just yet, now would be a
* good time.
*/
bool handle_pending_cannouncement(struct routing_state *rstate,
const struct short_channel_id *scid,
const u64 satoshis,
const u8 *txscript);
/* Returns NULL if all OK, otherwise an error for the peer which sent. */
u8 *handle_channel_update(struct routing_state *rstate, const u8 *update);
/* Returns NULL if all OK, otherwise an error for the peer which sent. */
u8 *handle_node_announcement(struct routing_state *rstate, const u8 *node);
/* Set values on the struct node_connection */
void set_connection_values(struct chan *chan,
int idx,
u32 base_fee,
u32 proportional_fee,
u32 delay,
bool active,
u64 timestamp,
u32 htlc_minimum_msat);
/* Get a node: use this instead of node_map_get() */
struct node *get_node(struct routing_state *rstate, const struct pubkey *id);
/* Compute a route to a destination, for a given amount and riskfactor. */
struct route_hop *get_route(const tal_t *ctx, struct routing_state *rstate,
const struct pubkey *source,
const struct pubkey *destination,
const u64 msatoshi, double riskfactor,
u32 final_cltv,
double fuzz,
const struct siphash_seed *base_seed);
/* Disable channel(s) based on the given routing failure. */
void routing_failure(struct routing_state *rstate,
const struct pubkey *erring_node,
const struct short_channel_id *erring_channel,
enum onion_type failcode,
const u8 *channel_update);
/* Disable specific channel from routing. */
void mark_channel_unroutable(struct routing_state *rstate,
const struct short_channel_id *channel);
void route_prune(struct routing_state *rstate);
/* Utility function that, given a source and a destination, gives us
* the direction bit the matching channel should get */
#define get_channel_direction(from, to) (pubkey_cmp(from, to) > 0)
/**
* Add a channel_announcement to the network view without checking it
*
* Directly add the channel to the local network, without checking it first. Use
* this only for messages from trusted sources. Untrusted sources should use the
* @see{handle_channel_announcement} entrypoint to check before adding.
*/
bool routing_add_channel_announcement(struct routing_state *rstate,
const u8 *msg TAKES, u64 satoshis);
/**
* Add a channel_update without checking for errors
*
* Used to actually insert the information in the channel update into the local
* network view. Only use this for messages that are known to be good. For
* untrusted source, requiring verification please use
* @see{handle_channel_update}
*/
bool routing_add_channel_update(struct routing_state *rstate,
const u8 *update TAKES);
/**
* Add a node_announcement to the network view without checking it
*
* Directly add the node being announced to the network view, without verifying
* it. This must be from a trusted source, e.g., gossip_store. For untrusted
* sources (peers) please use @see{handle_node_announcement}.
*/
bool routing_add_node_announcement(struct routing_state *rstate,
const u8 *msg TAKES);
/**
* Add a local channel.
*
* Entrypoint to add a local channel that was not learned through gossip. This
* is the case for private channels or channels that have not yet reached
* `announce_depth`.
*/
void handle_local_add_channel(struct routing_state *rstate, u8 *msg);
#endif /* LIGHTNING_GOSSIPD_ROUTING_H */