forked from ElementsProject/lightning
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathchaintopology.h
281 lines (229 loc) · 8.8 KB
/
chaintopology.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
#ifndef LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H
#define LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H
#include "config.h"
#include <bitcoin/block.h>
#include <ccan/list/list.h>
#include <lightningd/feerate.h>
#include <lightningd/watch.h>
struct bitcoin_tx;
struct bitcoind;
struct command;
struct lightningd;
struct peer;
struct txwatch;
/* We keep the last three in case there are outliers (for min/max) */
#define FEE_HISTORY_NUM 3
/* Off topology->outgoing_txs */
struct outgoing_tx {
struct channel *channel;
const struct bitcoin_tx *tx;
struct bitcoin_txid txid;
u32 minblock;
bool allowhighfees;
const char *cmd_id;
bool (*finished)(struct channel *channel, const struct bitcoin_tx *,
bool success, const char *err, void *arg);
bool (*refresh)(struct channel *, const struct bitcoin_tx **, void *arg);
void *cbarg;
};
struct block {
u32 height;
/* Actual header. */
struct bitcoin_block_hdr hdr;
/* Previous block (if any). */
struct block *prev;
/* Next block (if any). */
struct block *next;
/* Key for hash table */
struct bitcoin_blkid blkid;
/* Full copy of txs (freed in filter_block_txs) */
struct bitcoin_tx **full_txs;
struct bitcoin_txid *txids;
};
/* Hash blocks by sha */
static inline const struct bitcoin_blkid *keyof_block_map(const struct block *b)
{
return &b->blkid;
}
static inline size_t hash_sha(const struct bitcoin_blkid *key)
{
size_t ret;
memcpy(&ret, key, sizeof(ret));
return ret;
}
static inline bool block_eq(const struct block *b, const struct bitcoin_blkid *key)
{
return bitcoin_blkid_eq(&b->blkid, key);
}
HTABLE_DEFINE_TYPE(struct block, keyof_block_map, hash_sha, block_eq, block_map);
/* Hash blocks by sha */
static inline const struct bitcoin_txid *keyof_outgoing_tx_map(const struct outgoing_tx *t)
{
return &t->txid;
}
static inline size_t outgoing_tx_hash_sha(const struct bitcoin_txid *key)
{
size_t ret;
memcpy(&ret, key, sizeof(ret));
return ret;
}
static inline bool outgoing_tx_eq(const struct outgoing_tx *b, const struct bitcoin_txid *key)
{
return bitcoin_txid_eq(&b->txid, key);
}
HTABLE_DEFINE_TYPE(struct outgoing_tx, keyof_outgoing_tx_map,
outgoing_tx_hash_sha, outgoing_tx_eq, outgoing_tx_map);
/* Our plugins give us a series of blockcount, feerate pairs. */
struct feerate_est {
u32 blockcount;
u32 rate;
};
struct chain_topology {
struct lightningd *ld;
struct block *root;
struct block *tip;
struct bitcoin_blkid prev_tip;
struct block_map *block_map;
/* This is the lowest feerate that bitcoind is saying will broadcast. */
u32 feerate_floor;
/* We keep last three feerates we got: this is useful for min/max. */
struct feerate_est *feerates[FEE_HISTORY_NUM];
/* We keep a smoothed feerate: this is useful when we're going to
* suggest feerates / check feerates from our peers. */
struct feerate_est *smoothed_feerates;
/* Where to log things. */
struct logger *log;
/* How often to poll. */
u32 poll_seconds;
/* struct sync_waiters waiting for us to catch up with bitcoind (and
* once that has caught up with the network). NULL if we're already
* caught up. */
struct list_head *sync_waiters;
/* The bitcoind. */
struct bitcoind *bitcoind;
/* Timers we're running. */
struct oneshot *checkchain_timer, *extend_timer, *updatefee_timer, *rebroadcast_timer;
/* Parent context for requests (to bcli plugin) we have outstanding. */
tal_t *request_ctx;
/* Bitcoin transactions we're broadcasting */
struct outgoing_tx_map *outgoing_txs;
/* Transactions/txos we are watching. */
struct txwatch_hash *txwatches;
struct txowatch_hash *txowatches;
/* The number of headers known to the bitcoin backend at startup. Not
* updated after the initial check. */
u32 headercount;
};
/* Information relevant to locating a TX in a blockchain. */
struct txlocator {
/* The height of the block that includes this transaction */
u32 blkheight;
/* Position of the transaction in the transactions list */
u32 index;
};
/* Get the minimum feerate that bitcoind will accept */
u32 get_feerate_floor(const struct chain_topology *topo);
/* This is the number of blocks which would have to be mined to invalidate
* the tx */
size_t get_tx_depth(const struct chain_topology *topo,
const struct bitcoin_txid *txid);
/* Get highest block number. */
u32 get_block_height(const struct chain_topology *topo);
/* Get the highest block number in the network that we are aware of. Unlike
* `get_block_height` this takes into consideration the block header counter
* in the bitcoin backend as well. If an absolute time is required, rather
* than our current scan position this is preferable since it is far less
* likely to lag behind the rest of the network.*/
u32 get_network_blockheight(const struct chain_topology *topo);
/* Get feerate estimate for getting a tx in this many blocks */
u32 feerate_for_deadline(const struct chain_topology *topo, u32 blockcount);
u32 smoothed_feerate_for_deadline(const struct chain_topology *topo, u32 blockcount);
/* Get feerate to hit this *block number*. */
u32 feerate_for_target(const struct chain_topology *topo, u64 deadline);
/* Get range of feerates to insist other side abide by for normal channels.
* If we have to guess, sets *unknown to true, otherwise false. */
u32 feerate_min(struct lightningd *ld, bool *unknown);
u32 feerate_max(struct lightningd *ld, bool *unknown);
/* These return 0 if unknown */
u32 opening_feerate(struct chain_topology *topo);
u32 mutual_close_feerate(struct chain_topology *topo);
u32 unilateral_feerate(struct chain_topology *topo, bool option_anchors);
/* For onchain resolution. */
u32 delayed_to_us_feerate(struct chain_topology *topo);
u32 htlc_resolution_feerate(struct chain_topology *topo);
u32 penalty_feerate(struct chain_topology *topo);
/* Usually we set nLocktime to tip (or recent) like bitcoind does */
u32 default_locktime(const struct chain_topology *topo);
/**
* broadcast_tx - Broadcast a single tx, and rebroadcast as reqd (copies tx).
* @ctx: context: when this is freed, callback/retransmission don't happen.
* @topo: topology
* @channel: the channel responsible for this (stop broadcasting if freed).
* @tx: the transaction
* @cmd_id: the JSON command id which triggered this (or NULL).
* @allowhighfees: set to true to override the high-fee checks in the backend.
* @minblock: minimum block we can send it at (or 0).
* @finished: if non-NULL, call every time sendrawtransaction returns; if it returns true, don't rebroadcast.
* @refresh: if non-NULL, callback before re-broadcasting (can replace tx):
* if returns false, delete.
* @cbarg: argument for @finished and @refresh
*/
#define broadcast_tx(ctx, topo, channel, tx, cmd_id, allowhighfees, \
minblock, finished, refresh, cbarg) \
broadcast_tx_((ctx), (topo), (channel), (tx), (cmd_id), (allowhighfees), \
(minblock), \
typesafe_cb_preargs(bool, void *, \
(finished), (cbarg), \
struct channel *, \
const struct bitcoin_tx *, \
bool, const char *), \
typesafe_cb_preargs(bool, void *, \
(refresh), (cbarg), \
struct channel *, \
const struct bitcoin_tx **), \
(cbarg))
void broadcast_tx_(const tal_t *ctx,
struct chain_topology *topo,
struct channel *channel,
const struct bitcoin_tx *tx TAKES,
const char *cmd_id, bool allowhighfees, u32 minblock,
bool (*finished)(struct channel *,
const struct bitcoin_tx *,
bool success,
const char *err,
void *),
bool (*refresh)(struct channel *, const struct bitcoin_tx **, void *),
void *cbarg TAKES);
struct chain_topology *new_topology(struct lightningd *ld, struct logger *log);
void setup_topology(struct chain_topology *topology);
void begin_topology(struct chain_topology *topo);
void stop_topology(struct chain_topology *topo);
struct txlocator *locate_tx(const void *ctx, const struct chain_topology *topo, const struct bitcoin_txid *txid);
static inline bool topology_synced(const struct chain_topology *topo)
{
return topo->sync_waiters == NULL;
}
/**
* topology_add_sync_waiter: wait for lightningd to sync with bitcoin network
* @ctx: context to allocate the waiter from.
* @topo: chain topology
* @cb: callback to call when we're synced.
* @arg: arg for @cb
*
* topology_synced() must be false when this is called. It will be true
* when @cb is called. @cb will not be called if @ctx is freed first.
*/
void topology_add_sync_waiter_(const tal_t *ctx,
struct chain_topology *topo,
void (*cb)(struct chain_topology *,
void *),
void *arg);
#define topology_add_sync_waiter(ctx, topo, cb, arg) \
topology_add_sync_waiter_((ctx), (topo), \
typesafe_cb_preargs(void, void *, \
(cb), (arg), \
struct chain_topology *), \
(arg))
/* In channel_control.c */
void notify_feerate_change(struct lightningd *ld);
#endif /* LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H */