core-lightning/lightningd/chaintopology.h
Rusty Russell c956d9f5eb lightningd: tal memleak detection, dev-memleak command.
This is a primitive mark-and-sweep-style garbage detector.  The core is
in common/ for later use by subdaemons, but for now it's just lightningd.
We initialize it before most other allocations.

We walk the tal tree to get all the pointers, then search the `ld`
object for those pointers, recursing down.  Some specific helpers are
required for hashtables (which stash bits in the unused pointer bits,
so won't be found).

There's `notleak()` for annotating things that aren't leaks: things
like globals and timers, and other semi-transients.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2017-12-20 12:43:10 +01:00

178 lines
4.5 KiB
C

#ifndef LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H
#define LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H
#include "config.h"
#include <bitcoin/block.h>
#include <bitcoin/shadouble.h>
#include <ccan/list/list.h>
#include <ccan/short_types/short_types.h>
#include <ccan/structeq/structeq.h>
#include <ccan/time/time.h>
#include <jsmn.h>
#include <lightningd/watch.h>
#include <stddef.h>
struct bitcoin_tx;
struct bitcoind;
struct command;
struct lightningd;
struct peer;
struct sha256_double;
struct txwatch;
enum feerate {
FEERATE_IMMEDIATE, /* Aka: aim for next block. */
FEERATE_NORMAL, /* Aka: next 4 blocks or so. */
FEERATE_SLOW, /* Aka: next 100 blocks or so. */
};
#define NUM_FEERATES (FEERATE_SLOW+1)
/* Off topology->outgoing_txs */
struct outgoing_tx {
struct list_node list;
struct peer *peer;
const char *hextx;
struct sha256_double txid;
void (*failed)(struct peer *peer, int exitstatus, const char *err);
/* FIXME: Remove this. */
struct chain_topology *topo;
};
struct block {
int 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 sha256_double blkid;
/* Transactions in this block we care about */
const struct bitcoin_tx **txs;
/* And their associated index in the block */
u32 *txnums;
/* Full copy of txs (trimmed to txs list in connect_block) */
struct bitcoin_tx **full_txs;
/* FIXME: Remove this. */
struct chain_topology *topo;
};
/* Hash blocks by sha */
static inline const struct sha256_double *keyof_block_map(const struct block *b)
{
return &b->blkid;
}
static inline size_t hash_sha(const struct sha256_double *key)
{
size_t ret;
memcpy(&ret, key, sizeof(ret));
return ret;
}
static inline bool block_eq(const struct block *b, const struct sha256_double *key)
{
return structeq(&b->blkid, key);
}
HTABLE_DEFINE_TYPE(struct block, keyof_block_map, hash_sha, block_eq, block_map);
struct chain_topology {
struct block *root;
struct block *tip;
struct block_map block_map;
u32 feerate[NUM_FEERATES];
bool startup;
/* Where to log things. */
struct log *log;
/* How far back (in blocks) to go. */
unsigned int first_blocknum;
/* How often to poll. */
struct timerel poll_time;
/* The bitcoind. */
struct bitcoind *bitcoind;
/* Our timer list. */
struct timers *timers;
/* Bitcoin transactions we're broadcasting */
struct list_head outgoing_txs;
/* Force a particular fee rate regardless of estimatefee (satoshis/kb) */
u32 *override_fee_rate;
/* What fee we use if estimatefee fails (satoshis/kb) */
u32 default_fee_rate;
/* Transactions/txos we are watching. */
struct txwatch_hash txwatches;
struct txowatch_hash txowatches;
#if DEVELOPER
/* Suppress broadcast (for testing) */
bool dev_no_broadcast;
#endif
};
/* 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;
};
/* This is the number of blocks which would have to be mined to invalidate
* the tx (optional tx is filled in if return is non-zero). */
size_t get_tx_depth(const struct chain_topology *topo,
const struct sha256_double *txid,
const struct bitcoin_tx **tx);
/* Get highest block number. */
u32 get_block_height(const struct chain_topology *topo);
/* Get fee rate in satoshi per kiloweight. */
u32 get_feerate(const struct chain_topology *topo, enum feerate feerate);
/* Broadcast a single tx, and rebroadcast as reqd (copies tx).
* If failed is non-NULL, call that and don't rebroadcast. */
void broadcast_tx(struct chain_topology *topo,
struct peer *peer, const struct bitcoin_tx *tx,
void (*failed)(struct peer *peer,
int exitstatus,
const char *err));
struct chain_topology *new_topology(struct lightningd *ld, struct log *log);
void setup_topology(struct chain_topology *topology,
struct timers *timers,
struct timerel poll_time, u32 first_peer_block);
struct txlocator *locate_tx(const void *ctx, const struct chain_topology *topo, const struct sha256_double *txid);
void notify_new_block(struct lightningd *ld, unsigned int height);
void notify_feerate_change(struct lightningd *ld);
#if DEVELOPER
void json_dev_broadcast(struct command *cmd,
struct chain_topology *topo,
const char *buffer, const jsmntok_t *params);
void chaintopology_mark_pointers_used(struct htable *memtable,
const struct chain_topology *topo);
#endif
#endif /* LIGHTNING_LIGHTNINGD_CHAINTOPOLOGY_H */