rgb-cln/lightningd/chaintopology.h

276 lines
8.4 KiB
C

#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;
void (*finished)(struct channel *channel, bool success, const char *err);
bool (*refresh)(struct channel *, const struct bitcoin_tx **, void *arg);
void *refresh_arg;
};
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;
/* Set during startup */
bool feerate_uninitialized;
/* 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 log *log;
/* What range of blocks do we have in our database? */
u32 min_blockheight, max_blockheight;
/* 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 *extend_timer, *updatefee_timer, *rebroadcast_timer;
/* 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;
/* Are we stopped? */
bool stopping;
};
/* 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 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);
/* 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).
* @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 that and don't rebroadcast.
* @refresh: if non-NULL, callback before re-broadcasting (can replace tx):
* if returns false, delete.
* @refresh_arg: argument for @refresh
*/
#define broadcast_tx(topo, channel, tx, cmd_id, allowhighfees, \
minblock, finished, refresh, refresh_arg) \
broadcast_tx_((topo), (channel), (tx), (cmd_id), (allowhighfees), \
(minblock), (finished), \
typesafe_cb_preargs(bool, void *, \
(refresh), (refresh_arg), \
struct channel *, \
const struct bitcoin_tx **), \
(refresh_arg))
void broadcast_tx_(struct chain_topology *topo,
struct channel *channel,
const struct bitcoin_tx *tx TAKES,
const char *cmd_id, bool allowhighfees, u32 minblock,
void (*finished)(struct channel *,
bool success,
const char *err),
bool (*refresh)(struct channel *, const struct bitcoin_tx **, void *),
void *refresh_arg TAKES);
struct chain_topology *new_topology(struct lightningd *ld, struct log *log);
void setup_topology(struct chain_topology *topology,
u32 min_blockheight, u32 max_blockheight);
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 */