From 61e576ef1261a2caaa46573618d6697844db6d49 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 2 Mar 2017 22:51:49 +1030 Subject: [PATCH] daemon/chaintopology: use struct topology for more functions, not lightningd_state Signed-off-by: Rusty Russell --- daemon/chaintopology.c | 177 ++++++++++++++++++---------------------- daemon/chaintopology.h | 32 ++++++-- daemon/irc_announce.c | 2 +- daemon/jsonrpc.c | 3 +- daemon/lightningd.c | 6 +- daemon/p2p_announce.c | 4 +- daemon/pay.c | 3 +- daemon/peer.c | 66 ++++++++++----- daemon/peer.h | 4 +- daemon/watch.c | 3 +- lightningd/lightningd.c | 4 +- 11 files changed, 166 insertions(+), 138 deletions(-) diff --git a/daemon/chaintopology.c b/daemon/chaintopology.c index a108c0bb2..8c28a18f5 100644 --- a/daemon/chaintopology.c +++ b/daemon/chaintopology.c @@ -16,16 +16,16 @@ #include #include -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); diff --git a/daemon/chaintopology.h b/daemon/chaintopology.h index 9394d1712..b0d80e962 100644 --- a/daemon/chaintopology.h +++ b/daemon/chaintopology.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -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 */ diff --git a/daemon/irc_announce.c b/daemon/irc_announce.c index 9c75a4f23..9328d1098 100644 --- a/daemon/irc_announce.c +++ b/daemon/irc_announce.c @@ -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; diff --git a/daemon/jsonrpc.c b/daemon/jsonrpc.c index 345d680de..42659cb48 100644 --- a/daemon/jsonrpc.c +++ b/daemon/jsonrpc.c @@ -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); } diff --git a/daemon/lightningd.c b/daemon/lightningd.c index 597e80138..c92f134d5 100644 --- a/daemon/lightningd.c +++ b/daemon/lightningd.c @@ -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); diff --git a/daemon/p2p_announce.c b/daemon/p2p_announce.c index d77d57f02..144250549 100644 --- a/daemon/p2p_announce.c +++ b/daemon/p2p_announce.c @@ -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; diff --git a/daemon/pay.c b/daemon/pay.c index b139ee5b2..2c926ebb7 100644 --- a/daemon/pay.c +++ b/daemon/pay.c @@ -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) { diff --git a/daemon/peer.c b/daemon/peer.c index e2c5e10f2..d945a9185 100644 --- a/daemon/peer.c +++ b/daemon/peer.c @@ -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); } } diff --git a/daemon/peer.h b/daemon/peer.h index a5dc177b1..20f152740 100644 --- a/daemon/peer.h +++ b/daemon/peer.h @@ -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); diff --git a/daemon/watch.c b/daemon/watch.c index 2891e3da2..717f2eb22 100644 --- a/daemon/watch.c +++ b/daemon/watch.c @@ -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; diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index f82c3a32c..7ab15dd82 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -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;