mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
daemon/chaintopology: use struct topology for more functions, not lightningd_state
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -16,16 +16,16 @@
|
||||
#include <ccan/tal/str/str.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
static void start_poll_chaintip(struct lightningd_state *dstate);
|
||||
static void start_poll_chaintip(struct topology *topo);
|
||||
|
||||
static void next_topology_timer(struct lightningd_state *dstate)
|
||||
static void next_topology_timer(struct topology *topo)
|
||||
{
|
||||
if (dstate->topology->startup) {
|
||||
dstate->topology->startup = false;
|
||||
io_break(dstate);
|
||||
if (topo->startup) {
|
||||
topo->startup = false;
|
||||
io_break(topo);
|
||||
}
|
||||
new_reltimer(&dstate->timers, dstate, dstate->config.poll_time,
|
||||
start_poll_chaintip, dstate);
|
||||
new_reltimer(topo->timers, topo, topo->poll_time,
|
||||
start_poll_chaintip, topo);
|
||||
}
|
||||
|
||||
static int cmp_times(const u32 *a, const u32 *b, void *unused)
|
||||
@@ -64,11 +64,10 @@ static void add_tx_to_block(struct block *b, const struct sha256_double *txid, c
|
||||
b->txnums[n] = txnum;
|
||||
}
|
||||
|
||||
static bool we_broadcast(struct lightningd_state *dstate,
|
||||
static bool we_broadcast(const struct topology *topo,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct topology *topo = dstate->topology;
|
||||
struct outgoing_tx *otx;
|
||||
const struct outgoing_tx *otx;
|
||||
|
||||
list_for_each(&topo->outgoing_txs, otx, list) {
|
||||
if (structeq(&otx->txid, txid))
|
||||
@@ -78,11 +77,10 @@ static bool we_broadcast(struct lightningd_state *dstate,
|
||||
}
|
||||
|
||||
/* Fills in prev, height, mediantime. */
|
||||
static void connect_block(struct lightningd_state *dstate,
|
||||
static void connect_block(struct topology *topo,
|
||||
struct block *prev,
|
||||
struct block *b)
|
||||
{
|
||||
struct topology *topo = dstate->topology;
|
||||
size_t i;
|
||||
|
||||
assert(b->height == -1);
|
||||
@@ -116,13 +114,13 @@ static void connect_block(struct lightningd_state *dstate,
|
||||
|
||||
/* We did spends first, in case that tells us to watch tx. */
|
||||
bitcoin_txid(tx, &txid);
|
||||
if (watching_txid(topo, &txid) || we_broadcast(dstate, &txid))
|
||||
if (watching_txid(topo, &txid) || we_broadcast(topo, &txid))
|
||||
add_tx_to_block(b, &txid, i);
|
||||
}
|
||||
b->full_txs = tal_free(b->full_txs);
|
||||
|
||||
/* Tell peers about new block. */
|
||||
peers_new_block(dstate, b->height);
|
||||
notify_new_block(topo, b->height);
|
||||
}
|
||||
|
||||
static bool tx_in_block(const struct block *b,
|
||||
@@ -138,10 +136,9 @@ static bool tx_in_block(const struct block *b,
|
||||
}
|
||||
|
||||
/* FIXME: Use hash table. */
|
||||
static struct block *block_for_tx(struct lightningd_state *dstate,
|
||||
static struct block *block_for_tx(const struct topology *topo,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct topology *topo = dstate->topology;
|
||||
struct block *b;
|
||||
|
||||
for (b = topo->tip; b; b = b->prev) {
|
||||
@@ -151,13 +148,12 @@ static struct block *block_for_tx(struct lightningd_state *dstate,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t get_tx_depth(struct lightningd_state *dstate,
|
||||
size_t get_tx_depth(const struct topology *topo,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct topology *topo = dstate->topology;
|
||||
const struct block *b;
|
||||
|
||||
b = block_for_tx(dstate, txid);
|
||||
b = block_for_tx(topo, txid);
|
||||
if (!b)
|
||||
return 0;
|
||||
return topo->tip->height - b->height + 1;
|
||||
@@ -178,16 +174,14 @@ static void broadcast_remainder(struct bitcoind *bitcoind,
|
||||
int exitstatus, const char *msg,
|
||||
struct txs_to_broadcast *txs)
|
||||
{
|
||||
struct lightningd_state *dstate = tal_parent(bitcoind);
|
||||
|
||||
/* These are expected. */
|
||||
if (strstr(msg, "txn-mempool-conflict")
|
||||
|| strstr(msg, "transaction already in block chain"))
|
||||
log_debug(dstate->base_log,
|
||||
log_debug(bitcoind->log,
|
||||
"Expected error broadcasting tx %s: %s",
|
||||
txs->txs[txs->cursor], msg);
|
||||
else if (exitstatus)
|
||||
log_unusual(dstate->base_log, "Broadcasting tx %s: %i %s",
|
||||
log_unusual(bitcoind->log, "Broadcasting tx %s: %i %s",
|
||||
txs->txs[txs->cursor], exitstatus, msg);
|
||||
|
||||
txs->cursor++;
|
||||
@@ -205,25 +199,23 @@ static void broadcast_remainder(struct bitcoind *bitcoind,
|
||||
|
||||
/* FIXME: This is dumb. We can group txs and avoid bothering bitcoind
|
||||
* if any one tx is in the main chain. */
|
||||
static void rebroadcast_txs(struct lightningd_state *dstate,
|
||||
struct command *cmd)
|
||||
static void rebroadcast_txs(struct topology *topo, struct command *cmd)
|
||||
{
|
||||
/* Copy txs now (peers may go away, and they own txs). */
|
||||
size_t num_txs = 0;
|
||||
struct txs_to_broadcast *txs;
|
||||
struct topology *topo = dstate->topology;
|
||||
struct outgoing_tx *otx;
|
||||
|
||||
if (dstate->dev_no_broadcast)
|
||||
if (cmd->dstate->dev_no_broadcast)
|
||||
return;
|
||||
|
||||
txs = tal(dstate, struct txs_to_broadcast);
|
||||
txs = tal(topo, struct txs_to_broadcast);
|
||||
txs->cmd = cmd;
|
||||
|
||||
/* Put any txs we want to broadcast in ->txs. */
|
||||
txs->txs = tal_arr(txs, const char *, 0);
|
||||
list_for_each(&topo->outgoing_txs, otx, list) {
|
||||
if (block_for_tx(dstate, &otx->txid))
|
||||
if (block_for_tx(topo, &otx->txid))
|
||||
continue;
|
||||
|
||||
tal_resize(&txs->txs, num_txs+1);
|
||||
@@ -233,7 +225,7 @@ static void rebroadcast_txs(struct lightningd_state *dstate,
|
||||
|
||||
/* Let this do the dirty work. */
|
||||
txs->cursor = (size_t)-1;
|
||||
broadcast_remainder(dstate->bitcoind, 0, "", txs);
|
||||
broadcast_remainder(topo->bitcoind, 0, "", txs);
|
||||
}
|
||||
|
||||
static void destroy_outgoing_tx(struct outgoing_tx *otx)
|
||||
@@ -258,7 +250,8 @@ static void broadcast_done(struct bitcoind *bitcoind,
|
||||
}
|
||||
}
|
||||
|
||||
void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx,
|
||||
void broadcast_tx(struct topology *topo,
|
||||
struct peer *peer, const struct bitcoin_tx *tx,
|
||||
void (*failed)(struct peer *peer,
|
||||
int exitstatus, const char *err))
|
||||
{
|
||||
@@ -271,13 +264,13 @@ void broadcast_tx(struct peer *peer, const struct bitcoin_tx *tx,
|
||||
otx->failed = failed;
|
||||
tal_free(rawtx);
|
||||
|
||||
log_add_struct(peer->log, " (tx %s)", struct sha256_double, &otx->txid);
|
||||
log_add_struct(topo->bitcoind->log,
|
||||
" (tx %s)", struct sha256_double, &otx->txid);
|
||||
|
||||
if (peer->dstate->dev_no_broadcast)
|
||||
broadcast_done(peer->dstate->bitcoind,
|
||||
0, "dev_no_broadcast", otx);
|
||||
broadcast_done(topo->bitcoind, 0, "dev_no_broadcast", otx);
|
||||
else
|
||||
bitcoind_sendrawtx(peer, peer->dstate->bitcoind, otx->hextx,
|
||||
bitcoind_sendrawtx(peer, topo->bitcoind, otx->hextx,
|
||||
broadcast_done, otx);
|
||||
}
|
||||
|
||||
@@ -306,41 +299,39 @@ static void update_fee(struct bitcoind *bitcoind, u64 rate, u64 *feerate)
|
||||
}
|
||||
|
||||
/* B is the new chain (linked by ->next); update topology */
|
||||
static void topology_changed(struct lightningd_state *dstate,
|
||||
static void topology_changed(struct topology *topo,
|
||||
struct block *prev,
|
||||
struct block *b)
|
||||
{
|
||||
/* Eliminate any old chain. */
|
||||
if (prev->next)
|
||||
free_blocks(dstate->topology, prev->next);
|
||||
free_blocks(topo, prev->next);
|
||||
|
||||
prev->next = b;
|
||||
do {
|
||||
connect_block(dstate, prev, b);
|
||||
dstate->topology->tip = prev = b;
|
||||
connect_block(topo, prev, b);
|
||||
topo->tip = prev = b;
|
||||
b = b->next;
|
||||
} while (b);
|
||||
|
||||
/* Tell watch code to re-evaluate all txs. */
|
||||
watch_topology_changed(dstate->topology);
|
||||
watch_topology_changed(topo);
|
||||
|
||||
/* Maybe need to rebroadcast. */
|
||||
rebroadcast_txs(dstate, NULL);
|
||||
rebroadcast_txs(topo, NULL);
|
||||
|
||||
/* Once per new block head, update fee estimate. */
|
||||
bitcoind_estimate_fee(dstate->bitcoind,
|
||||
update_fee, &dstate->topology->feerate);
|
||||
bitcoind_estimate_fee(topo->bitcoind, update_fee, &topo->feerate);
|
||||
}
|
||||
|
||||
static struct block *new_block(struct lightningd_state *dstate,
|
||||
static struct block *new_block(struct topology *topo,
|
||||
struct bitcoin_block *blk,
|
||||
struct block *next)
|
||||
{
|
||||
struct topology *topo = dstate->topology;
|
||||
struct block *b = tal(topo, struct block);
|
||||
|
||||
sha256_double(&b->blkid, &blk->hdr, sizeof(blk->hdr));
|
||||
log_debug_struct(dstate->base_log, "Adding block %s",
|
||||
log_debug_struct(topo->bitcoind->log, "Adding block %s",
|
||||
struct sha256_double, &b->blkid);
|
||||
assert(!block_map_get(&topo->block_map, &b->blkid));
|
||||
b->next = next;
|
||||
@@ -367,7 +358,7 @@ static void gather_blocks(struct bitcoind *bitcoind,
|
||||
struct topology *topo = dstate->topology;
|
||||
struct block *b, *prev;
|
||||
|
||||
b = new_block(dstate, blk, next);
|
||||
b = new_block(topo, blk, next);
|
||||
|
||||
/* Recurse if we need prev. */
|
||||
prev = block_map_get(&topo->block_map, &blk->hdr.prev_hash);
|
||||
@@ -378,103 +369,88 @@ static void gather_blocks(struct bitcoind *bitcoind,
|
||||
}
|
||||
|
||||
/* All done. */
|
||||
topology_changed(dstate, prev, b);
|
||||
next_topology_timer(dstate);
|
||||
topology_changed(topo, prev, b);
|
||||
next_topology_timer(topo);
|
||||
}
|
||||
|
||||
static void check_chaintip(struct bitcoind *bitcoind,
|
||||
const struct sha256_double *tipid,
|
||||
void *arg)
|
||||
struct topology *topo)
|
||||
{
|
||||
struct lightningd_state *dstate = tal_parent(bitcoind);
|
||||
struct topology *topo = dstate->topology;
|
||||
|
||||
/* 0 is the main tip. */
|
||||
if (!structeq(tipid, &topo->tip->blkid))
|
||||
bitcoind_getrawblock(dstate->bitcoind, tipid, gather_blocks,
|
||||
bitcoind_getrawblock(bitcoind, tipid, gather_blocks,
|
||||
(struct block *)NULL);
|
||||
else
|
||||
/* Next! */
|
||||
next_topology_timer(dstate);
|
||||
next_topology_timer(topo);
|
||||
}
|
||||
|
||||
static void start_poll_chaintip(struct lightningd_state *dstate)
|
||||
static void start_poll_chaintip(struct topology *topo)
|
||||
{
|
||||
if (!list_empty(&dstate->bitcoind->pending)) {
|
||||
log_unusual(dstate->base_log,
|
||||
if (!list_empty(&topo->bitcoind->pending)) {
|
||||
log_unusual(topo->bitcoind->log,
|
||||
"Delaying start poll: commands in progress");
|
||||
next_topology_timer(dstate);
|
||||
next_topology_timer(topo);
|
||||
} else
|
||||
bitcoind_get_chaintip(dstate->bitcoind, check_chaintip, NULL);
|
||||
bitcoind_get_chaintip(topo->bitcoind, check_chaintip, topo);
|
||||
}
|
||||
|
||||
static void init_topo(struct bitcoind *bitcoind,
|
||||
struct bitcoin_block *blk,
|
||||
ptrint_t *p)
|
||||
struct topology *topo)
|
||||
{
|
||||
struct lightningd_state *dstate = tal_parent(bitcoind);
|
||||
struct topology *topo = dstate->topology;
|
||||
|
||||
topo->root = new_block(dstate, blk, NULL);
|
||||
topo->root->height = ptr2int(p);
|
||||
topo->root = new_block(topo, blk, NULL);
|
||||
topo->root->height = topo->first_blocknum;
|
||||
block_map_add(&topo->block_map, topo->root);
|
||||
topo->tip = topo->root;
|
||||
|
||||
/* Now grab chaintip immediately. */
|
||||
bitcoind_get_chaintip(dstate->bitcoind, check_chaintip, NULL);
|
||||
bitcoind_get_chaintip(bitcoind, check_chaintip, topo);
|
||||
}
|
||||
|
||||
static void get_init_block(struct bitcoind *bitcoind,
|
||||
const struct sha256_double *blkid,
|
||||
ptrint_t *blknum)
|
||||
struct topology *topo)
|
||||
{
|
||||
bitcoind_getrawblock(bitcoind, blkid, init_topo, blknum);
|
||||
bitcoind_getrawblock(bitcoind, blkid, init_topo, topo);
|
||||
}
|
||||
|
||||
static void get_init_blockhash(struct bitcoind *bitcoind, u32 blockcount,
|
||||
void *unused)
|
||||
struct topology *topo)
|
||||
{
|
||||
struct lightningd_state *dstate = tal_parent(bitcoind);
|
||||
u32 start;
|
||||
struct peer *peer;
|
||||
|
||||
/* Start back before any reasonable forks. */
|
||||
if (blockcount < dstate->config.forever_confirms)
|
||||
start = 0;
|
||||
else
|
||||
start = blockcount - dstate->config.forever_confirms;
|
||||
|
||||
/* If loaded from database, go back to earliest possible peer anchor. */
|
||||
list_for_each(&dstate->peers, peer, list) {
|
||||
if (peer->anchor.min_depth && peer->anchor.min_depth < start)
|
||||
start = peer->anchor.min_depth;
|
||||
}
|
||||
if (blockcount < 100)
|
||||
topo->first_blocknum = 0;
|
||||
else if (!topo->first_blocknum || blockcount - 100 < topo->first_blocknum)
|
||||
topo->first_blocknum = blockcount - 100;
|
||||
|
||||
/* Start topology from 100 blocks back. */
|
||||
bitcoind_getblockhash(bitcoind, start, get_init_block, int2ptr(start));
|
||||
bitcoind_getblockhash(bitcoind, topo->first_blocknum,
|
||||
get_init_block, topo);
|
||||
}
|
||||
|
||||
u32 get_tx_mediantime(struct lightningd_state *dstate,
|
||||
u32 get_tx_mediantime(const struct topology *topo,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct block *b;
|
||||
|
||||
b = block_for_tx(dstate, txid);
|
||||
b = block_for_tx(topo, txid);
|
||||
if (b)
|
||||
return b->mediantime;
|
||||
|
||||
fatal("Tx %s not found for get_tx_mediantime",
|
||||
tal_hexstr(dstate, txid, sizeof(*txid)));
|
||||
tal_hexstr(topo, txid, sizeof(*txid)));
|
||||
}
|
||||
|
||||
u32 get_tip_mediantime(struct lightningd_state *dstate)
|
||||
u32 get_tip_mediantime(const struct topology *topo)
|
||||
{
|
||||
return dstate->topology->tip->mediantime;
|
||||
return topo->tip->mediantime;
|
||||
}
|
||||
|
||||
u32 get_block_height(struct lightningd_state *dstate)
|
||||
u32 get_block_height(const struct topology *topo)
|
||||
{
|
||||
return dstate->topology->tip->height;
|
||||
return topo->tip->height;
|
||||
}
|
||||
|
||||
u64 get_feerate(struct lightningd_state *dstate)
|
||||
@@ -492,10 +468,10 @@ u64 get_feerate(struct lightningd_state *dstate)
|
||||
return dstate->topology->feerate;
|
||||
}
|
||||
|
||||
struct txlocator *locate_tx(const void *ctx, struct lightningd_state *dstate,
|
||||
struct txlocator *locate_tx(const void *ctx, const struct topology *topo,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
struct block *block = block_for_tx(dstate, txid);
|
||||
struct block *block = block_for_tx(topo, txid);
|
||||
if (block == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
@@ -536,7 +512,7 @@ static void json_dev_broadcast(struct command *cmd,
|
||||
|
||||
/* If enabling, flush and wait. */
|
||||
if (enable)
|
||||
rebroadcast_txs(cmd->dstate, cmd);
|
||||
rebroadcast_txs(cmd->dstate->topology, cmd);
|
||||
else
|
||||
command_success(cmd, null_response(cmd));
|
||||
}
|
||||
@@ -571,11 +547,18 @@ struct topology *new_topology(const tal_t *ctx)
|
||||
return topo;
|
||||
}
|
||||
|
||||
void setup_topology(struct topology *topo, struct bitcoind *bitcoind)
|
||||
void setup_topology(struct topology *topo, struct bitcoind *bitcoind,
|
||||
struct timers *timers,
|
||||
struct timerel poll_time, u32 first_peer_block)
|
||||
{
|
||||
topo->startup = true;
|
||||
topo->feerate = 0;
|
||||
bitcoind_getblockcount(bitcoind, get_init_blockhash, NULL);
|
||||
topo->timers = timers;
|
||||
topo->bitcoind = bitcoind;
|
||||
topo->poll_time = poll_time;
|
||||
topo->first_blocknum = first_peer_block;
|
||||
|
||||
bitcoind_getblockcount(bitcoind, get_init_blockhash, topo);
|
||||
|
||||
tal_add_destructor(topo, destroy_outgoing_txs);
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <ccan/list/list.h>
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/structeq/structeq.h>
|
||||
#include <ccan/time/time.h>
|
||||
#include <daemon/watch.h>
|
||||
#include <stddef.h>
|
||||
|
||||
@@ -80,6 +81,18 @@ struct topology {
|
||||
u64 feerate;
|
||||
bool startup;
|
||||
|
||||
/* 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 transctions we're broadcasting */
|
||||
struct list_head outgoing_txs;
|
||||
|
||||
@@ -100,32 +113,37 @@ struct txlocator {
|
||||
|
||||
/* This is the number of blocks which would have to be mined to invalidate
|
||||
* the tx. */
|
||||
size_t get_tx_depth(struct lightningd_state *dstate,
|
||||
size_t get_tx_depth(const struct topology *topo,
|
||||
const struct sha256_double *txid);
|
||||
|
||||
/* Get the mediantime of the block including this tx (must be one!) */
|
||||
u32 get_tx_mediantime(struct lightningd_state *dstate,
|
||||
u32 get_tx_mediantime(const struct topology *topo,
|
||||
const struct sha256_double *txid);
|
||||
|
||||
/* Get mediantime of the tip; if more than one, pick greatest time. */
|
||||
u32 get_tip_mediantime(struct lightningd_state *dstate);
|
||||
u32 get_tip_mediantime(const struct topology *topo);
|
||||
|
||||
/* Get highest block number. */
|
||||
u32 get_block_height(struct lightningd_state *dstate);
|
||||
u32 get_block_height(const struct topology *topo);
|
||||
|
||||
/* Get fee rate. */
|
||||
u64 get_feerate(struct lightningd_state *dstate);
|
||||
|
||||
/* 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 peer *peer, const struct bitcoin_tx *tx,
|
||||
void broadcast_tx(struct topology *topo,
|
||||
struct peer *peer, const struct bitcoin_tx *tx,
|
||||
void (*failed)(struct peer *peer,
|
||||
int exitstatus,
|
||||
const char *err));
|
||||
|
||||
struct topology *new_topology(const tal_t *ctx);
|
||||
void setup_topology(struct topology *topology, struct bitcoind *bitcoind);
|
||||
void setup_topology(struct topology *topology, struct bitcoind *bitcoind,
|
||||
struct timers *timers,
|
||||
struct timerel poll_time, u32 first_peer_block);
|
||||
|
||||
struct txlocator *locate_tx(const void *ctx, struct lightningd_state *dstate, const struct sha256_double *txid);
|
||||
struct txlocator *locate_tx(const void *ctx, const struct topology *topo, const struct sha256_double *txid);
|
||||
|
||||
void notify_new_block(struct topology *topo, unsigned int height);
|
||||
|
||||
#endif /* LIGHTNING_DAEMON_CRYPTOPKT_H */
|
||||
|
||||
@@ -28,7 +28,7 @@ static bool announce_channel(const tal_t *ctx, struct ircstate *state, struct pe
|
||||
{
|
||||
char txid[65];
|
||||
struct privmsg *msg = talz(ctx, struct privmsg);
|
||||
struct txlocator *loc = locate_tx(ctx, state->dstate, &p->anchor.txid);
|
||||
struct txlocator *loc = locate_tx(ctx, state->dstate->topology, &p->anchor.txid);
|
||||
|
||||
if (loc == NULL)
|
||||
return false;
|
||||
|
||||
@@ -275,7 +275,8 @@ static void json_getinfo(struct command *cmd,
|
||||
json_add_num(response, "port", cmd->dstate->portnum);
|
||||
json_add_bool(response, "testnet", cmd->dstate->testnet);
|
||||
json_add_string(response, "version", version());
|
||||
json_add_num(response, "blockheight", get_block_height(cmd->dstate));
|
||||
json_add_num(response, "blockheight",
|
||||
get_block_height(cmd->dstate->topology));
|
||||
json_object_end(response);
|
||||
command_success(cmd, response);
|
||||
}
|
||||
|
||||
@@ -66,8 +66,8 @@ int main(int argc, char *argv[])
|
||||
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
|
||||
| SECP256K1_CONTEXT_SIGN);
|
||||
|
||||
dstate->bitcoind = new_bitcoind(dstate, dstate->base_log);
|
||||
dstate->topology = new_topology(dstate);
|
||||
dstate->bitcoind = new_bitcoind(dstate, dstate->base_log);
|
||||
|
||||
/* Handle options and config; move to .lightningd */
|
||||
register_opts(dstate);
|
||||
@@ -87,7 +87,9 @@ int main(int argc, char *argv[])
|
||||
db_init(dstate);
|
||||
|
||||
/* Initialize block topology. */
|
||||
setup_topology(dstate->topology, dstate->bitcoind);
|
||||
setup_topology(dstate->topology, dstate->bitcoind, &dstate->timers,
|
||||
dstate->config.poll_time,
|
||||
get_peer_min_block(dstate));
|
||||
|
||||
/* Create RPC socket (if any) */
|
||||
setup_jsonrpc(dstate, dstate->rpc_filename);
|
||||
|
||||
@@ -22,7 +22,7 @@ static void broadcast_channel_update(struct lightningd_state *dstate, struct pee
|
||||
u32 timestamp = time_now().ts.tv_sec;
|
||||
const tal_t *tmpctx = tal_tmpctx(dstate);
|
||||
|
||||
loc = locate_tx(tmpctx, dstate, &peer->anchor.txid);
|
||||
loc = locate_tx(tmpctx, dstate->topology, &peer->anchor.txid);
|
||||
channel_id.blocknum = loc->blkheight;
|
||||
channel_id.txnum = loc->index;
|
||||
channel_id.outnum = peer->anchor.index;
|
||||
@@ -105,7 +105,7 @@ static void broadcast_channel_announcement(struct lightningd_state *dstate, stru
|
||||
u8 *serialized;
|
||||
const tal_t *tmpctx = tal_tmpctx(dstate);
|
||||
|
||||
loc = locate_tx(tmpctx, dstate, &peer->anchor.txid);
|
||||
loc = locate_tx(tmpctx, dstate->topology, &peer->anchor.txid);
|
||||
|
||||
channel_id.blocknum = loc->blkheight;
|
||||
channel_id.txnum = loc->index;
|
||||
|
||||
@@ -462,7 +462,8 @@ static void json_sendpay(struct command *cmd,
|
||||
|
||||
/* Expiry for HTLCs is absolute. And add one to give some margin. */
|
||||
err = command_htlc_add(peer, amount,
|
||||
delay + get_block_height(cmd->dstate) + 1,
|
||||
delay + get_block_height(cmd->dstate->topology)
|
||||
+ 1,
|
||||
&rhash, NULL,
|
||||
onion, &error_code, &pc->htlc);
|
||||
if (err) {
|
||||
|
||||
@@ -347,14 +347,15 @@ static void peer_breakdown(struct peer *peer)
|
||||
if (peer->closing.their_sig) {
|
||||
const struct bitcoin_tx *close = mk_bitcoin_close(peer, peer);
|
||||
log_unusual(peer->log, "Peer breakdown: sending close tx");
|
||||
broadcast_tx(peer, close, NULL);
|
||||
broadcast_tx(peer->dstate->topology, peer, close, NULL);
|
||||
tal_free(close);
|
||||
/* If we have a signed commit tx (maybe not if we just offered
|
||||
* anchor, or they supplied anchor, or no outputs to us). */
|
||||
} else if (peer->local.commit && peer->local.commit->sig) {
|
||||
log_unusual(peer->log, "Peer breakdown: sending commit tx");
|
||||
sign_commit_tx(peer);
|
||||
broadcast_tx(peer, peer->local.commit->tx, NULL);
|
||||
broadcast_tx(peer->dstate->topology, peer,
|
||||
peer->local.commit->tx, NULL);
|
||||
} else {
|
||||
log_info(peer->log, "Peer breakdown: nothing to do");
|
||||
/* We close immediately. */
|
||||
@@ -644,7 +645,8 @@ static bool open_ouranchor_pkt_in(struct peer *peer, const Pkt *pkt)
|
||||
if (db_commit_transaction(peer) != NULL)
|
||||
return peer_database_err(peer);
|
||||
|
||||
broadcast_tx(peer, peer->anchor.tx, funding_tx_failed);
|
||||
broadcast_tx(peer->dstate->topology,
|
||||
peer, peer->anchor.tx, funding_tx_failed);
|
||||
peer_watch_anchor(peer, peer->local.mindepth);
|
||||
return true;
|
||||
}
|
||||
@@ -878,7 +880,7 @@ static void their_htlc_added(struct peer *peer, struct htlc *htlc,
|
||||
}
|
||||
|
||||
if (abs_locktime_to_blocks(&htlc->expiry) <=
|
||||
get_block_height(peer->dstate) + peer->dstate->config.min_htlc_expiry) {
|
||||
get_block_height(peer->dstate->topology) + peer->dstate->config.min_htlc_expiry) {
|
||||
log_unusual(peer->log, "HTLC %"PRIu64" expires too soon:"
|
||||
" block %u",
|
||||
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
||||
@@ -888,7 +890,7 @@ static void their_htlc_added(struct peer *peer, struct htlc *htlc,
|
||||
}
|
||||
|
||||
if (abs_locktime_to_blocks(&htlc->expiry) >
|
||||
get_block_height(peer->dstate) + peer->dstate->config.max_htlc_expiry) {
|
||||
get_block_height(peer->dstate->topology) + peer->dstate->config.max_htlc_expiry) {
|
||||
log_unusual(peer->log, "HTLC %"PRIu64" expires too far:"
|
||||
" block %u",
|
||||
htlc->id, abs_locktime_to_blocks(&htlc->expiry));
|
||||
@@ -1313,7 +1315,7 @@ static bool closing_pkt_in(struct peer *peer, const Pkt *pkt)
|
||||
* SHOULD sign and broadcast the final closing transaction.
|
||||
*/
|
||||
close = mk_bitcoin_close(peer, peer);
|
||||
broadcast_tx(peer, close, NULL);
|
||||
broadcast_tx(peer->dstate->topology, peer, close, NULL);
|
||||
tal_free(close);
|
||||
return false;
|
||||
}
|
||||
@@ -2058,7 +2060,8 @@ static bool fulfill_onchain(struct peer *peer, struct htlc *htlc)
|
||||
return false;
|
||||
peer->onchain.resolved[i]
|
||||
= htlc_fulfill_tx(peer, i);
|
||||
broadcast_tx(peer, peer->onchain.resolved[i], NULL);
|
||||
broadcast_tx(peer->dstate->topology,
|
||||
peer, peer->onchain.resolved[i], NULL);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -2106,14 +2109,14 @@ const char *command_htlc_add(struct peer *peer, u64 msatoshi,
|
||||
return "bad expiry";
|
||||
}
|
||||
|
||||
if (expiry < get_block_height(peer->dstate) + peer->dstate->config.min_htlc_expiry) {
|
||||
if (expiry < get_block_height(peer->dstate->topology) + peer->dstate->config.min_htlc_expiry) {
|
||||
log_unusual(peer->log, "add_htlc: fail: expiry %u is too soon",
|
||||
expiry);
|
||||
*error_code = BAD_REQUEST_400;
|
||||
return "expiry too soon";
|
||||
}
|
||||
|
||||
if (expiry > get_block_height(peer->dstate) + peer->dstate->config.max_htlc_expiry) {
|
||||
if (expiry > get_block_height(peer->dstate->topology) + peer->dstate->config.max_htlc_expiry) {
|
||||
log_unusual(peer->log, "add_htlc: fail: expiry %u is too far",
|
||||
expiry);
|
||||
*error_code = BAD_REQUEST_400;
|
||||
@@ -2842,7 +2845,7 @@ static bool peer_first_connected(struct peer *peer,
|
||||
peer->conn = conn;
|
||||
io_set_finish(conn, peer_disconnect, peer);
|
||||
|
||||
peer->anchor.min_depth = get_block_height(peer->dstate);
|
||||
peer->anchor.min_depth = get_block_height(peer->dstate->topology);
|
||||
|
||||
/* FIXME: Attach IO logging for this peer. */
|
||||
if (!netaddr_from_fd(io_conn_fd(conn), addr_type, addr_protocol, &addr))
|
||||
@@ -3249,7 +3252,7 @@ AUTODATA(json_command, &connect_command);
|
||||
/* Have any of our HTLCs passed their deadline? */
|
||||
static bool any_deadline_past(struct peer *peer)
|
||||
{
|
||||
u32 height = get_block_height(peer->dstate);
|
||||
u32 height = get_block_height(peer->dstate->topology);
|
||||
struct htlc_map_iter it;
|
||||
struct htlc *h;
|
||||
|
||||
@@ -3272,7 +3275,7 @@ static bool any_deadline_past(struct peer *peer)
|
||||
|
||||
static void check_htlc_expiry(struct peer *peer)
|
||||
{
|
||||
u32 height = get_block_height(peer->dstate);
|
||||
u32 height = get_block_height(peer->dstate->topology);
|
||||
struct htlc_map_iter it;
|
||||
struct htlc *h;
|
||||
|
||||
@@ -3400,8 +3403,9 @@ static enum watch_result anchor_depthchange(struct peer *peer,
|
||||
return KEEP_WATCHING;
|
||||
}
|
||||
|
||||
void peers_new_block(struct lightningd_state *dstate, unsigned int height)
|
||||
void notify_new_block(struct topology *topo, unsigned int height)
|
||||
{
|
||||
struct lightningd_state *dstate = tal_parent(topo);
|
||||
/* This is where we check for anchor timeouts. */
|
||||
struct peer *peer;
|
||||
|
||||
@@ -3632,7 +3636,7 @@ static enum watch_result our_htlc_depth(struct peer *peer,
|
||||
if (depth == 0)
|
||||
return KEEP_WATCHING;
|
||||
|
||||
height = get_block_height(peer->dstate);
|
||||
height = get_block_height(peer->dstate->topology);
|
||||
|
||||
/* FIXME-OLD #onchain:
|
||||
*
|
||||
@@ -3663,7 +3667,8 @@ static enum watch_result our_htlc_depth(struct peer *peer,
|
||||
peer,
|
||||
peer->onchain.resolved[out_num],
|
||||
our_htlc_timeout_depth, h);
|
||||
broadcast_tx(peer, peer->onchain.resolved[out_num], NULL);
|
||||
broadcast_tx(peer->dstate->topology,
|
||||
peer, peer->onchain.resolved[out_num], NULL);
|
||||
}
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
@@ -3696,7 +3701,7 @@ static enum watch_result their_htlc_depth(struct peer *peer,
|
||||
if (depth == 0)
|
||||
return KEEP_WATCHING;
|
||||
|
||||
height = get_block_height(peer->dstate);
|
||||
height = get_block_height(peer->dstate->topology);
|
||||
|
||||
/* FIXME-OLD #onchain:
|
||||
*
|
||||
@@ -3732,7 +3737,8 @@ static enum watch_result our_main_output_depth(struct peer *peer,
|
||||
*/
|
||||
peer->onchain.resolved[peer->onchain.to_us_idx]
|
||||
= bitcoin_spend_ours(peer);
|
||||
broadcast_tx(peer, peer->onchain.resolved[peer->onchain.to_us_idx],
|
||||
broadcast_tx(peer->dstate->topology,
|
||||
peer, peer->onchain.resolved[peer->onchain.to_us_idx],
|
||||
NULL);
|
||||
return DELETE_WATCH;
|
||||
}
|
||||
@@ -3852,7 +3858,8 @@ static void resolve_their_htlc(struct peer *peer, unsigned int out_num)
|
||||
*/
|
||||
if (peer->onchain.htlcs[out_num]->r) {
|
||||
peer->onchain.resolved[out_num] = htlc_fulfill_tx(peer, out_num);
|
||||
broadcast_tx(peer, peer->onchain.resolved[out_num], NULL);
|
||||
broadcast_tx(peer->dstate->topology,
|
||||
peer, peer->onchain.resolved[out_num], NULL);
|
||||
} else {
|
||||
/* FIXME-OLD #onchain:
|
||||
*
|
||||
@@ -4012,7 +4019,7 @@ static enum watch_result check_for_resolution(struct peer *peer,
|
||||
struct sha256_double txid;
|
||||
|
||||
bitcoin_txid(peer->onchain.resolved[i], &txid);
|
||||
if (get_tx_depth(peer->dstate, &txid) < forever)
|
||||
if (get_tx_depth(peer->dstate->topology, &txid) < forever)
|
||||
return KEEP_WATCHING;
|
||||
}
|
||||
|
||||
@@ -4146,7 +4153,7 @@ static void resolve_their_steal(struct peer *peer,
|
||||
}
|
||||
assert(n == tal_count(steal_tx->input));
|
||||
|
||||
broadcast_tx(peer, steal_tx, NULL);
|
||||
broadcast_tx(peer->dstate->topology, peer, steal_tx, NULL);
|
||||
}
|
||||
|
||||
static struct sha256 *get_rhash(struct peer *peer, u64 commit_num,
|
||||
@@ -4485,6 +4492,22 @@ void reconnect_peers(struct lightningd_state *dstate)
|
||||
try_reconnect(peer);
|
||||
}
|
||||
|
||||
/* Return earliest block we're interested in, or 0 for none. */
|
||||
u32 get_peer_min_block(struct lightningd_state *dstate)
|
||||
{
|
||||
u32 min_block = 0;
|
||||
struct peer *peer;
|
||||
|
||||
/* If loaded from database, go back to earliest possible peer anchor. */
|
||||
list_for_each(&dstate->peers, peer, list) {
|
||||
if (!peer->anchor.min_depth)
|
||||
continue;
|
||||
if (min_block == 0 || peer->anchor.min_depth < min_block)
|
||||
min_block = peer->anchor.min_depth;
|
||||
}
|
||||
return min_block;
|
||||
}
|
||||
|
||||
/* We may have gone down before broadcasting the anchor. Try again. */
|
||||
void rebroadcast_anchors(struct lightningd_state *dstate)
|
||||
{
|
||||
@@ -4498,7 +4521,8 @@ void rebroadcast_anchors(struct lightningd_state *dstate)
|
||||
if (!bitcoin_create_anchor(peer))
|
||||
peer_fail(peer, __func__);
|
||||
else
|
||||
broadcast_tx(peer, peer->anchor.tx, NULL);
|
||||
broadcast_tx(peer->dstate->topology,
|
||||
peer, peer->anchor.tx, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -270,8 +270,6 @@ const char *command_htlc_add(struct peer *peer, u64 msatoshi,
|
||||
enum fail_error *error_code,
|
||||
struct htlc **htlc);
|
||||
|
||||
void peers_new_block(struct lightningd_state *dstate, unsigned int height);
|
||||
|
||||
/* Peer has an issue, breakdown and fail. */
|
||||
void peer_fail(struct peer *peer, const char *caller);
|
||||
|
||||
@@ -280,6 +278,8 @@ void peer_watch_anchor(struct peer *peer, int depth);
|
||||
struct bitcoin_tx *peer_create_close_tx(const tal_t *ctx,
|
||||
struct peer *peer, u64 fee);
|
||||
|
||||
u32 get_peer_min_block(struct lightningd_state *dstate);
|
||||
|
||||
void debug_dump_peers(struct lightningd_state *dstate);
|
||||
|
||||
void reconnect_peers(struct lightningd_state *dstate);
|
||||
|
||||
@@ -221,7 +221,6 @@ void watch_topology_changed(struct topology *topo)
|
||||
struct txwatch_hash_iter i;
|
||||
struct txwatch *w;
|
||||
bool needs_rerun;
|
||||
struct lightningd_state *dstate = tal_parent(topo);
|
||||
|
||||
again:
|
||||
/* Iterating a htable during deletes is safe, but might skip entries. */
|
||||
@@ -231,7 +230,7 @@ again:
|
||||
w = txwatch_hash_next(&topo->txwatches, &i)) {
|
||||
size_t depth;
|
||||
|
||||
depth = get_tx_depth(dstate, &w->txid);
|
||||
depth = get_tx_depth(topo, &w->txid);
|
||||
if (depth != w->depth) {
|
||||
enum watch_result r;
|
||||
w->depth = depth;
|
||||
|
||||
@@ -42,7 +42,7 @@ struct peer *find_peer(struct lightningd_state *dstate, const struct pubkey *id)
|
||||
FIXME_IMPLEMENT();
|
||||
}
|
||||
|
||||
size_t get_tx_depth(struct lightningd_state *dstate,
|
||||
size_t get_tx_depth(const struct topology *topo,
|
||||
const struct sha256_double *txid)
|
||||
{
|
||||
FIXME_IMPLEMENT();
|
||||
@@ -54,7 +54,7 @@ void debug_dump_peers(struct lightningd_state *dstate)
|
||||
FIXME_IMPLEMENT();
|
||||
}
|
||||
|
||||
u32 get_block_height(struct lightningd_state *dstate)
|
||||
u32 get_block_height(const struct topology *topo)
|
||||
{
|
||||
/* FIXME_IMPLEMENT(); */
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user