diff options
author | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-06-24 16:26:05 +0200 |
---|---|---|
committer | Wladimir J. van der Laan <laanwj@gmail.com> | 2017-06-24 16:37:42 +0200 |
commit | bef02fb6ac9f57fdb490f6a5725cde6bde0da124 (patch) | |
tree | c369995b06a606b0ecf29ba06aa49346600b0987 /src/wallet/wallet.cpp | |
parent | eee398fa123ff677f24f2211e8d3012650530c32 (diff) | |
parent | deaf48b046e573f6774d19e74b58918ed777cb14 (diff) | |
download | bitcoin-bef02fb6ac9f57fdb490f6a5725cde6bde0da124.tar.xz |
Merge #10412: Improve wallet rescan API
deaf48b Handle TIMESTAMP_WINDOW within CWallet::RescanFromTime (Russell Yanofsky)
5b2be2b Make CWallet::RescanFromTime comment less ambiguous (Russell Yanofsky)
9bb66ab Add RescanFromTime method and use from rpcdump (Russell Yanofsky)
ccf84bb Move birthday optimization out of ScanForWalletTransactions (Russell Yanofsky)
Tree-SHA512: cd38433b8f5c5e44ecfba830a6a26bd9a9d0f4a22ae42bce17773d1a6fb25e1ee4289484996dad2d7acfa03059917ff062459f25030a761da7083ba5fbc87bc9
Diffstat (limited to 'src/wallet/wallet.cpp')
-rw-r--r-- | src/wallet/wallet.cpp | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index f07a6cb5a5..0d1a86dd24 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -220,6 +220,10 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigne return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret); } +/** + * Update wallet first key creation time. This should be called whenever keys + * are added to the wallet, with the oldest key creation time. + */ void CWallet::UpdateTimeFirstKey(int64_t nCreateTime) { AssertLockHeld(cs_wallet); @@ -1468,6 +1472,34 @@ void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived, } /** + * Scan active chain for relevant transactions after importing keys. This should + * be called whenever new keys are added to the wallet, with the oldest key + * creation time. + * + * @return Earliest timestamp that could be successfully scanned from. Timestamp + * returned will be higher than startTime if relevant blocks could not be read. + */ +int64_t CWallet::RescanFromTime(int64_t startTime, bool update) +{ + AssertLockHeld(cs_main); + AssertLockHeld(cs_wallet); + + // Find starting block. May be null if nCreateTime is greater than the + // highest blockchain timestamp, in which case there is nothing that needs + // to be scanned. + CBlockIndex* const startBlock = chainActive.FindEarliestAtLeast(startTime - TIMESTAMP_WINDOW); + LogPrintf("%s: Rescanning last %i blocks\n", __func__, startBlock ? chainActive.Height() - startBlock->nHeight + 1 : 0); + + if (startBlock) { + const CBlockIndex* const failedBlock = ScanForWalletTransactions(startBlock, update); + if (failedBlock) { + return failedBlock->GetBlockTimeMax() + TIMESTAMP_WINDOW + 1; + } + } + return startTime; +} + +/** * Scan the block chain (starting in pindexStart) for transactions * from or to us. If fUpdate is true, found transactions that already * exist in the wallet will be updated. @@ -1488,11 +1520,6 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f fAbortRescan = false; fScanningWallet = true; - // no need to read and scan block, if block was created before - // our wallet birthday (as adjusted for block time variability) - while (pindex && nTimeFirstKey && (pindex->GetBlockTime() < (nTimeFirstKey - TIMESTAMP_WINDOW))) - pindex = chainActive.Next(pindex); - ShowProgress(_("Rescanning..."), 0); // show rescan progress in GUI as dialog or on splashscreen, if -rescan on startup double dProgressStart = GuessVerificationProgress(chainParams.TxData(), pindex); double dProgressTip = GuessVerificationProgress(chainParams.TxData(), chainActive.Tip()); @@ -3881,6 +3908,13 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile) uiInterface.InitMessage(_("Rescanning...")); LogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight); + + // No need to read and scan block if block was created before + // our wallet birthday (as adjusted for block time variability) + while (pindexRescan && walletInstance->nTimeFirstKey && (pindexRescan->GetBlockTime() < (walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW))) { + pindexRescan = chainActive.Next(pindexRescan); + } + nStart = GetTimeMillis(); walletInstance->ScanForWalletTransactions(pindexRescan, true); LogPrintf(" rescan %15dms\n", GetTimeMillis() - nStart); |