Automatically rescan after restoring wallet.dat

Information about the best known chain is added to wallet.dat. If this
information does not match the data in blkindex.dat, a rescan is automatically
performed, starting from the the last known block. When upgrading from a wallet
which does not have this information, no rescan is done automatically.
This commit is contained in:
Pieter Wuille 2011-04-13 16:16:30 +02:00 committed by Gavin Andresen
parent 657cfe721b
commit 6a76c60e6c
3 changed files with 33 additions and 1 deletions

12
db.h
View File

@ -13,6 +13,7 @@ class CAddress;
class CWalletTx; class CWalletTx;
class CAccount; class CAccount;
class CAccountingEntry; class CAccountingEntry;
class CBlockLocator;
extern map<string, string> mapAddressBook; extern map<string, string> mapAddressBook;
extern CCriticalSection cs_mapAddressBook; extern CCriticalSection cs_mapAddressBook;
@ -405,6 +406,17 @@ public:
return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false); return Write(make_pair(string("key"), vchPubKey), vchPrivKey, false);
} }
bool WriteBestBlock(const CBlockLocator& locator)
{
nWalletDBUpdated++;
return Write(string("bestblock"), locator);
}
bool ReadBestBlock(CBlockLocator& locator)
{
return Read(string("bestblock"), locator);
}
bool ReadDefaultKey(vector<unsigned char>& vchPubKey) bool ReadDefaultKey(vector<unsigned char>& vchPubKey)
{ {
vchPubKey.clear(); vchPubKey.clear();

View File

@ -372,10 +372,21 @@ bool AppInit2(int argc, char* argv[])
strErrors += _("Error loading wallet.dat \n"); strErrors += _("Error loading wallet.dat \n");
printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf(" wallet %15"PRI64d"ms\n", GetTimeMillis() - nStart);
CBlockIndex *pindexRescan = pindexBest;
if (GetBoolArg("-rescan")) if (GetBoolArg("-rescan"))
pindexRescan = pindexGenesisBlock;
else
{ {
CWalletDB walletdb;
CBlockLocator locator;
if (walletdb.ReadBestBlock(locator))
pindexRescan = locator.GetBlockIndex();
}
if (pindexBest != pindexRescan)
{
printf("Rescanning last %i blocks (from block %i)...\n", pindexBest->nHeight - pindexRescan->nHeight, pindexRescan->nHeight);
nStart = GetTimeMillis(); nStart = GetTimeMillis();
ScanForWalletTransactions(pindexGenesisBlock); ScanForWalletTransactions(pindexRescan);
printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart); printf(" rescan %15"PRI64d"ms\n", GetTimeMillis() - nStart);
} }

View File

@ -1611,6 +1611,15 @@ bool CBlock::SetBestChain(CTxDB& txdb, CBlockIndex* pindexNew)
} }
} }
// Update best block in wallet (so we can detect restored wallets)
if (!IsInitialBlockDownload())
{
CWalletDB walletdb;
const CBlockLocator locator(pindexNew);
if (!walletdb.WriteBestBlock(locator))
return error("SetBestChain() : WriteWalletBest failed");
}
// New best block // New best block
hashBestChain = hash; hashBestChain = hash;
pindexBest = pindexNew; pindexBest = pindexNew;