Skip to content

Commit 9bb66ab

Browse files
committed
Add RescanFromTime method and use from rpcdump
No change in behavior.
1 parent ccf84bb commit 9bb66ab

File tree

3 files changed

+44
-17
lines changed

3 files changed

+44
-17
lines changed

src/wallet/rpcdump.cpp

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ UniValue importprivkey(const JSONRPCRequest& request)
149149
pwallet->UpdateTimeFirstKey(1);
150150

151151
if (fRescan) {
152-
pwallet->ScanForWalletTransactions(chainActive.Genesis(), true);
152+
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */);
153153
}
154154
}
155155

@@ -279,7 +279,7 @@ UniValue importaddress(const JSONRPCRequest& request)
279279

280280
if (fRescan)
281281
{
282-
pwallet->ScanForWalletTransactions(chainActive.Genesis(), true);
282+
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */);
283283
pwallet->ReacceptWalletTransactions();
284284
}
285285

@@ -437,7 +437,7 @@ UniValue importpubkey(const JSONRPCRequest& request)
437437

438438
if (fRescan)
439439
{
440-
pwallet->ScanForWalletTransactions(chainActive.Genesis(), true);
440+
pwallet->RescanFromTime(TIMESTAMP_MIN, true /* update */);
441441
pwallet->ReacceptWalletTransactions();
442442
}
443443

@@ -537,11 +537,7 @@ UniValue importwallet(const JSONRPCRequest& request)
537537
file.close();
538538
pwallet->ShowProgress("", 100); // hide progress dialog in GUI
539539
pwallet->UpdateTimeFirstKey(nTimeBegin);
540-
541-
CBlockIndex *pindex = chainActive.FindEarliestAtLeast(nTimeBegin - TIMESTAMP_WINDOW);
542-
543-
LogPrintf("Rescanning last %i blocks\n", pindex ? chainActive.Height() - pindex->nHeight + 1 : 0);
544-
pwallet->ScanForWalletTransactions(pindex);
540+
pwallet->RescanFromTime(nTimeBegin - TIMESTAMP_WINDOW, false /* update */);
545541
pwallet->MarkDirty();
546542

547543
if (!fGood)
@@ -1117,14 +1113,10 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
11171113
}
11181114

11191115
if (fRescan && fRunScan && requests.size()) {
1120-
CBlockIndex* pindex = nLowestTimestamp > minimumTimestamp ? chainActive.FindEarliestAtLeast(std::max<int64_t>(nLowestTimestamp - TIMESTAMP_WINDOW, 0)) : chainActive.Genesis();
1121-
CBlockIndex* scanFailed = nullptr;
1122-
if (pindex) {
1123-
scanFailed = pwallet->ScanForWalletTransactions(pindex, true);
1124-
pwallet->ReacceptWalletTransactions();
1125-
}
1116+
int64_t scannedTime = pwallet->RescanFromTime(nLowestTimestamp - TIMESTAMP_WINDOW, true /* update */);
1117+
pwallet->ReacceptWalletTransactions();
11261118

1127-
if (scanFailed) {
1119+
if (scannedTime > nLowestTimestamp - TIMESTAMP_WINDOW) {
11281120
std::vector<UniValue> results = response.getValues();
11291121
response.clear();
11301122
response.setArray();
@@ -1134,7 +1126,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
11341126
// range, or if the import result already has an error set, let
11351127
// the result stand unmodified. Otherwise replace the result
11361128
// with an error message.
1137-
if (GetImportTimestamp(request, now) - TIMESTAMP_WINDOW > scanFailed->GetBlockTimeMax() || results.at(i).exists("error")) {
1129+
if (scannedTime <= GetImportTimestamp(request, now) - TIMESTAMP_WINDOW || results.at(i).exists("error")) {
11381130
response.push_back(results.at(i));
11391131
} else {
11401132
UniValue result = UniValue(UniValue::VOBJ);
@@ -1150,7 +1142,7 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
11501142
"caused by pruning or data corruption (see bitcoind log for details) and could "
11511143
"be dealt with by downloading and rescanning the relevant blocks (see -reindex "
11521144
"and -rescan options).",
1153-
GetImportTimestamp(request, now), scanFailed->GetBlockTimeMax(), TIMESTAMP_WINDOW)));
1145+
GetImportTimestamp(request, now), scannedTime - 1, TIMESTAMP_WINDOW)));
11541146
response.push_back(std::move(result));
11551147
}
11561148
++i;

src/wallet/wallet.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,10 @@ bool CWallet::LoadCryptedKey(const CPubKey &vchPubKey, const std::vector<unsigne
221221
return CCryptoKeyStore::AddCryptedKey(vchPubKey, vchCryptedSecret);
222222
}
223223

224+
/**
225+
* Update wallet first key creation time. This should be called whenever keys
226+
* are added to the wallet, with the oldest key creation time.
227+
*/
224228
void CWallet::UpdateTimeFirstKey(int64_t nCreateTime)
225229
{
226230
AssertLockHeld(cs_wallet);
@@ -1458,6 +1462,34 @@ void CWalletTx::GetAmounts(std::list<COutputEntry>& listReceived,
14581462

14591463
}
14601464

1465+
/**
1466+
* Scan active chain for relevant transactions after importing keys. This should
1467+
* be called whenever new keys are added to the wallet, with the oldest key
1468+
* creation time minus TIMESTAMP_WINDOW.
1469+
*
1470+
* @return Earliest timestamp that could be successfully scanned from. Timestamp
1471+
* returned may be higher than startTime if some blocks could not be read.
1472+
*/
1473+
int64_t CWallet::RescanFromTime(int64_t startTime, bool update)
1474+
{
1475+
AssertLockHeld(cs_main);
1476+
AssertLockHeld(cs_wallet);
1477+
1478+
// Find starting block. May be null if nCreateTime is greater than the
1479+
// highest blockchain timestamp, in which case there is nothing that needs
1480+
// to be scanned.
1481+
CBlockIndex* const startBlock = chainActive.FindEarliestAtLeast(startTime);
1482+
LogPrintf("%s: Rescanning last %i blocks\n", __func__, startBlock ? chainActive.Height() - startBlock->nHeight + 1 : 0);
1483+
1484+
if (startBlock) {
1485+
const CBlockIndex* const failedBlock = ScanForWalletTransactions(startBlock, update);
1486+
if (failedBlock) {
1487+
return failedBlock->GetBlockTimeMax() + 1;
1488+
}
1489+
}
1490+
return startTime;
1491+
}
1492+
14611493
/**
14621494
* Scan the block chain (starting in pindexStart) for transactions
14631495
* from or to us. If fUpdate is true, found transactions that already

src/wallet/wallet.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ static const bool DEFAULT_USE_HD_WALLET = true;
6767

6868
extern const char * DEFAULT_WALLET_DAT;
6969

70+
static const int64_t TIMESTAMP_MIN = 0;
71+
7072
class CBlockIndex;
7173
class CCoinControl;
7274
class COutput;
@@ -918,6 +920,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
918920
void BlockConnected(const std::shared_ptr<const CBlock>& pblock, const CBlockIndex *pindex, const std::vector<CTransactionRef>& vtxConflicted) override;
919921
void BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) override;
920922
bool AddToWalletIfInvolvingMe(const CTransactionRef& tx, const CBlockIndex* pIndex, int posInBlock, bool fUpdate);
923+
int64_t RescanFromTime(int64_t startTime, bool update);
921924
CBlockIndex* ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate = false);
922925
void ReacceptWalletTransactions();
923926
void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) override;

0 commit comments

Comments
 (0)