diff --git a/lightningd/chaintopology.c b/lightningd/chaintopology.c index 610f16422..532c34cc6 100644 --- a/lightningd/chaintopology.c +++ b/lightningd/chaintopology.c @@ -519,17 +519,18 @@ static void get_init_block(struct bitcoind *bitcoind, static void get_init_blockhash(struct bitcoind *bitcoind, u32 blockcount, struct chain_topology *topo) { - /* This can happen if bitcoind still syncing, or first_blocknum is MAX */ - if (blockcount < topo->first_blocknum) - topo->first_blocknum = blockcount; - - /* For fork protection (esp. because we don't handle our own first - * block getting reorged out), we always go 100 blocks further back - * than we need. */ - if (topo->first_blocknum < 100) - topo->first_blocknum = 0; - else - topo->first_blocknum -= 100; + /* If bitcoind's current blockheight is below the requested height, just + * go back to that height. This might be a new node catching up, or + * bitcoind is processing a reorg. */ + if (blockcount < topo->first_blocknum) { + if (bitcoind->ld->config.rescan < 0) { + /* Absolute blockheight, but bitcoind's blockheight isn't there yet */ + topo->first_blocknum = blockcount - 1; + } else if (topo->first_blocknum == UINT32_MAX) { + /* Relative rescan, but we didn't know the blockheight */ + topo->first_blocknum = blockcount - bitcoind->ld->config.rescan; + } + } /* Rollback to the given blockheight, so we start track * correctly again */ diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index 104a63a36..fdf079352 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -282,7 +282,7 @@ int main(int argc, char *argv[]) { struct lightningd *ld; bool newdir; - u32 first_blocknum; + u32 blockheight; daemon_setup(argv[0], log_backtrace_print, log_backtrace_exit); ld = new_lightningd(NULL); @@ -357,10 +357,20 @@ int main(int argc, char *argv[]) if (!wallet_htlcs_reconnect(ld->wallet, &ld->htlcs_in, &ld->htlcs_out)) fatal("could not reconnect htlcs loaded from wallet, wallet may be inconsistent."); - /* Worst case, scan back to the first lightning deployment */ - first_blocknum = wallet_first_blocknum(ld->wallet, - get_chainparams(ld) - ->when_lightning_became_cool); + /* Get the blockheight we are currently at, UINT32_MAX is used to signal + * an unitialized wallet and that we should start off of bitcoind's + * current height */ + blockheight = wallet_blocks_height(ld->wallet, UINT32_MAX); + + /* If we were asked to rescan from an absolute height (--rescan < 0) + * then just go there. Otherwise take compute the diff to our current + * height, lowerbounded by 0. */ + if (ld->config.rescan < 0) + blockheight = -ld->config.rescan; + else if (blockheight < (u32)ld->config.rescan) + blockheight = 0; + else if (blockheight != UINT32_MAX) + blockheight -= ld->config.rescan; db_commit_transaction(ld->wallet->db); @@ -368,7 +378,7 @@ int main(int argc, char *argv[]) setup_topology(ld->topology, &ld->timers, ld->config.poll_time, - first_blocknum); + blockheight); /* Replay transactions for all running onchainds */ onchaind_replay_channels(ld); diff --git a/lightningd/test/run-find_my_path.c b/lightningd/test/run-find_my_path.c index 0be2ab349..f10cddc54 100644 --- a/lightningd/test/run-find_my_path.c +++ b/lightningd/test/run-find_my_path.c @@ -107,12 +107,12 @@ struct txfilter *txfilter_new(const tal_t *ctx UNNEEDED) /* Generated stub for version */ const char *version(void) { fprintf(stderr, "version called!\n"); abort(); } +/* Generated stub for wallet_blocks_height */ +u32 wallet_blocks_height(struct wallet *w UNNEEDED, u32 def UNNEEDED) +{ fprintf(stderr, "wallet_blocks_height called!\n"); abort(); } /* Generated stub for wallet_channels_load_active */ bool wallet_channels_load_active(const tal_t *ctx UNNEEDED, struct wallet *w UNNEEDED) { fprintf(stderr, "wallet_channels_load_active called!\n"); abort(); } -/* Generated stub for wallet_first_blocknum */ -u32 wallet_first_blocknum(struct wallet *w UNNEEDED, u32 first_possible UNNEEDED) -{ fprintf(stderr, "wallet_first_blocknum called!\n"); abort(); } /* Generated stub for wallet_htlcs_load_for_channel */ bool wallet_htlcs_load_for_channel(struct wallet *wallet UNNEEDED, struct channel *chan UNNEEDED, diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index 4cae2c354..189e7320e 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -3607,6 +3607,7 @@ class LightningDTests(BaseLightningDTests): def test_funding_while_offline(self): l1 = self.node_factory.get_node() addr = l1.rpc.newaddr()['address'] + sync_blockheight([l1]) # l1 goes down. l1.stop() diff --git a/wallet/wallet.c b/wallet/wallet.c index 259a5daa0..1f1bfc124 100644 --- a/wallet/wallet.c +++ b/wallet/wallet.c @@ -767,14 +767,7 @@ void wallet_channel_stats_load(struct wallet *w, stats->out_msatoshi_fulfilled = sqlite3_column_int64(stmt, 7); } -/* We want the earlier of either: - * 1. The first channel we're still watching (it might have closed), - * 2. The last block we scanned for UTXO (might have new incoming payments) - * - * chaintopology actually subtracts another 100 blocks to make sure we - * catch chain forks. - */ -u32 wallet_first_blocknum(struct wallet *w, u32 first_possible) +u32 wallet_blocks_height(struct wallet *w, u32 def) { u32 blockheight; sqlite3_stmt *stmt = db_prepare(w->db, "SELECT MAX(height) FROM blocks;"); @@ -785,7 +778,7 @@ u32 wallet_first_blocknum(struct wallet *w, u32 first_possible) sqlite3_finalize(stmt); return blockheight; } else - return first_possible; + return def; } static void wallet_channel_config_insert(struct wallet *w, diff --git a/wallet/wallet.h b/wallet/wallet.h index e940d6c7c..f754efad7 100644 --- a/wallet/wallet.h +++ b/wallet/wallet.h @@ -314,12 +314,15 @@ void wallet_channel_stats_incr_out_fulfilled(struct wallet *w, u64 cdbid, u64 ms void wallet_channel_stats_load(struct wallet *w, u64 cdbid, struct channel_stats *stats); /** - * wallet_first_blocknum - get first block we're interested in. + * Retrieve the blockheight of the last block processed by lightningd. + * + * Will return either the maximal blockheight or the default value if the wallet + * was never used before. * * @w: wallet to load from. - * @first_possible: when c-lightning may have been active from + * @def: the default value to return if we've never used the wallet before */ -u32 wallet_first_blocknum(struct wallet *w, u32 first_possible); +u32 wallet_blocks_height(struct wallet *w, u32 def); /** * wallet_extract_owned_outputs - given a tx, extract all of our outputs