diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index c05a66c1b..104a63a36 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -369,6 +370,9 @@ int main(int argc, char *argv[]) ld->config.poll_time, first_blocknum); + /* Replay transactions for all running onchainds */ + onchaind_replay_channels(ld); + /* Create RPC socket (if any) */ setup_jsonrpc(ld, ld->rpc_filename); diff --git a/lightningd/onchain_control.c b/lightningd/onchain_control.c index 40b383cec..52ad3f4eb 100644 --- a/lightningd/onchain_control.c +++ b/lightningd/onchain_control.c @@ -3,7 +3,6 @@ #include #include #include -#include #include #include #include @@ -469,3 +468,47 @@ enum watch_result onchaind_funding_spent(struct channel *channel, /* We keep watching until peer finally deleted, for reorgs. */ return KEEP_WATCHING; } + +void onchaind_replay_channels(struct lightningd *ld) +{ + u32 *onchaind_ids; + struct channeltx *txs; + struct channel *chan; + + db_begin_transaction(ld->wallet->db); + onchaind_ids = wallet_onchaind_channels(ld->wallet, ld); + + for (size_t i = 0; i < tal_count(onchaind_ids); i++) { + log_info(ld->log, "Restarting onchaind for channel %d", + onchaind_ids[i]); + + txs = wallet_channeltxs_get(ld->wallet, onchaind_ids, + onchaind_ids[i]); + chan = channel_by_dbid(ld, onchaind_ids[i]); + + for (size_t j = 0; j < tal_count(txs); j++) { + if (txs[j].type == WIRE_ONCHAIN_INIT) { + onchaind_funding_spent(chan, txs[j].tx, + txs[j].blockheight); + + } else if (txs[j].type == WIRE_ONCHAIN_SPENT) { + onchain_txo_spent(chan, txs[j].tx, + txs[j].input_num, + txs[j].blockheight); + + } else if (txs[j].type == WIRE_ONCHAIN_DEPTH) { + onchain_tx_depth(chan, &txs[j].txid, + txs[j].depth); + + } else { + fatal("unknown message of type %d during " + "onchaind replay", + txs[j].type); + } + } + tal_free(txs); + } + tal_free(onchaind_ids); + + db_commit_transaction(ld->wallet->db); +} diff --git a/lightningd/onchain_control.h b/lightningd/onchain_control.h index b7366ec5a..7ecfdf8a2 100644 --- a/lightningd/onchain_control.h +++ b/lightningd/onchain_control.h @@ -2,6 +2,8 @@ #define LIGHTNING_LIGHTNINGD_ONCHAIN_CONTROL_H #include "config.h" #include +#include +#include struct channel; struct bitcoin_tx; @@ -11,4 +13,6 @@ enum watch_result onchaind_funding_spent(struct channel *channel, const struct bitcoin_tx *tx, u32 blockheight); +void onchaind_replay_channels(struct lightningd *ld); + #endif /* LIGHTNING_LIGHTNINGD_ONCHAIN_CONTROL_H */ diff --git a/lightningd/test/run-find_my_path.c b/lightningd/test/run-find_my_path.c index 498a7aa54..0be2ab349 100644 --- a/lightningd/test/run-find_my_path.c +++ b/lightningd/test/run-find_my_path.c @@ -74,6 +74,9 @@ struct log_book *new_log_book(size_t max_mem UNNEEDED, /* Generated stub for new_topology */ struct chain_topology *new_topology(struct lightningd *ld UNNEEDED, struct log *log UNNEEDED) { fprintf(stderr, "new_topology called!\n"); abort(); } +/* Generated stub for onchaind_replay_channels */ +void onchaind_replay_channels(struct lightningd *ld UNNEEDED) +{ fprintf(stderr, "onchaind_replay_channels called!\n"); abort(); } /* Generated stub for register_opts */ void register_opts(struct lightningd *ld UNNEEDED) { fprintf(stderr, "register_opts called!\n"); abort(); }