Skip to content

Commit 30abce7

Browse files
committed
Improve ScanForWalletTransactions return value
Change ScanForWalletTransactions return value so it is possible to distinguish scans that skip reading every block (due to the nTimeFirstKey optimization) from scans that fail while reading the chainActive.Tip() block. Return value is now non-null in the non-failing case. This change doesn't affect any user-visible behavior, it is only an internal API improvement. The only code currently using the ScanForWalletTransactions return value is in importmulti, and importmulti always calls ScanForWalletTransactions with a pindex pointing to the first block in chainActive whose block time is >= (nLowestTimestamp - 7200), while ScanForWalletTransactions would only return null without reading blocks when pindex and every block after it had a block time < (nTimeFirstKey - 7200). These conditions could never happen at the same time because nTimeFirstKey <= nLowestTimestamp. I'm planning to make a more substantial API improvement in the future (making ScanForWalletTransactions private and exposing a higher level rescan method to RPC code), but Matt Corallo <[email protected]> pointed out this odd behavior introduced by e2e2f4c "Return errors from importmulti if complete rescans are not successful" yesterday, so I'm following up now to get rid of badness introduced by that merge.
1 parent 3fabae7 commit 30abce7

File tree

2 files changed

+15
-3
lines changed

2 files changed

+15
-3
lines changed

src/wallet/test/wallet_tests.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,17 @@ BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup)
426426
BOOST_CHECK_EQUAL(response.write(), strprintf("[{\"success\":false,\"error\":{\"code\":-1,\"message\":\"Failed to rescan before time %d, transactions may be missing.\"}},{\"success\":true}]", newTip->GetBlockTimeMax()));
427427
::pwalletMain = backup;
428428
}
429+
430+
// Verify ScanForWalletTransactions does not return null when the scan is
431+
// elided due to the nTimeFirstKey optimization.
432+
{
433+
CWallet wallet;
434+
{
435+
LOCK(wallet.cs_wallet);
436+
wallet.UpdateTimeFirstKey(newTip->GetBlockTime() + 7200 + 1);
437+
}
438+
BOOST_CHECK_EQUAL(newTip, wallet.ScanForWalletTransactions(newTip));
439+
}
429440
}
430441

431442
BOOST_AUTO_TEST_SUITE_END()

src/wallet/wallet.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1547,16 +1547,17 @@ void CWalletTx::GetAccountAmounts(const string& strAccount, CAmount& nReceived,
15471547
* exist in the wallet will be updated.
15481548
*
15491549
* Returns pointer to the first block in the last contiguous range that was
1550-
* successfully scanned.
1551-
*
1550+
* successfully scanned or elided (elided if pIndexStart points at a block
1551+
* before CWallet::nTimeFirstKey). Returns null if there is no such range, or
1552+
* the range doesn't include chainActive.Tip().
15521553
*/
15531554
CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
15541555
{
1555-
CBlockIndex* ret = nullptr;
15561556
int64_t nNow = GetTime();
15571557
const CChainParams& chainParams = Params();
15581558

15591559
CBlockIndex* pindex = pindexStart;
1560+
CBlockIndex* ret = pindexStart;
15601561
{
15611562
LOCK2(cs_main, cs_wallet);
15621563

0 commit comments

Comments
 (0)