diff --git a/src/wallet/test/wallet_tests.cpp b/src/wallet/test/wallet_tests.cpp --- a/src/wallet/test/wallet_tests.cpp +++ b/src/wallet/test/wallet_tests.cpp @@ -31,9 +31,7 @@ wallet.AddKeyPubKey(key, key.GetPubKey()); } -// Note: when backporting PR14957, see PR15321 and ensure both LockAnnotations -// are in place. -BOOST_FIXTURE_TEST_CASE(rescan, TestChain100Setup) { +BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup) { auto chain = interfaces::MakeChain(); // Cap last block file size, and mine new block in a new block file. @@ -46,6 +44,24 @@ LockAnnotation lock(::cs_main); auto locked_chain = chain->lock(); + // Verify ScanForWalletTransactions accommodates a null start block. + { + CWallet wallet(Params(), *chain, WalletLocation(), + WalletDatabase::CreateDummy()); + AddKey(wallet, coinbaseKey); + WalletRescanReserver reserver(&wallet); + reserver.reserve(); + const CBlockIndex *stop_block = null_block + 1, + *failed_block = null_block + 1; + BOOST_CHECK_EQUAL( + wallet.ScanForWalletTransactions(nullptr, nullptr, reserver, + failed_block, stop_block), + CWallet::ScanResult::SUCCESS); + BOOST_CHECK_EQUAL(failed_block, null_block); + BOOST_CHECK_EQUAL(stop_block, null_block); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), Amount::zero()); + } + // Verify ScanForWalletTransactions picks up transactions in both the old // and new block files. { @@ -54,7 +70,8 @@ AddKey(wallet, coinbaseKey); WalletRescanReserver reserver(&wallet); reserver.reserve(); - const CBlockIndex *stop_block, *failed_block; + const CBlockIndex *stop_block = null_block + 1, + *failed_block = null_block + 1; BOOST_CHECK_EQUAL( wallet.ScanForWalletTransactions(oldTip, nullptr, reserver, failed_block, stop_block), @@ -76,7 +93,8 @@ AddKey(wallet, coinbaseKey); WalletRescanReserver reserver(&wallet); reserver.reserve(); - const CBlockIndex *stop_block, *failed_block; + const CBlockIndex *stop_block = null_block + 1, + *failed_block = null_block + 1; BOOST_CHECK_EQUAL( wallet.ScanForWalletTransactions(oldTip, nullptr, reserver, failed_block, stop_block), @@ -86,6 +104,45 @@ BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), 50 * COIN); } + // Prune the remaining block file. + PruneOneBlockFile(newTip->GetBlockPos().nFile); + UnlinkPrunedFiles({newTip->GetBlockPos().nFile}); + + // Verify ScanForWalletTransactions scans no blocks. + { + CWallet wallet(Params(), *chain, WalletLocation(), + WalletDatabase::CreateDummy()); + AddKey(wallet, coinbaseKey); + WalletRescanReserver reserver(&wallet); + reserver.reserve(); + const CBlockIndex *stop_block = null_block + 1, + *failed_block = null_block + 1; + BOOST_CHECK_EQUAL( + wallet.ScanForWalletTransactions(oldTip, nullptr, reserver, + failed_block, stop_block), + CWallet::ScanResult::FAILURE); + BOOST_CHECK_EQUAL(failed_block, newTip); + BOOST_CHECK_EQUAL(stop_block, null_block); + BOOST_CHECK_EQUAL(wallet.GetImmatureBalance(), Amount::zero()); + } +} + +BOOST_FIXTURE_TEST_CASE(importmulti_rescan, TestChain100Setup) { + auto chain = interfaces::MakeChain(); + + // Cap last block file size, and mine new block in a new block file. + CBlockIndex *oldTip = ::ChainActive().Tip(); + GetBlockFileInfo(oldTip->GetBlockPos().nFile)->nSize = MAX_BLOCKFILE_SIZE; + CreateAndProcessBlock({}, GetScriptForRawPubKey(coinbaseKey.GetPubKey())); + CBlockIndex *newTip = ::ChainActive().Tip(); + + LockAnnotation lock(::cs_main); + auto locked_chain = chain->lock(); + + // Prune the older block file. + PruneOneBlockFile(oldTip->GetBlockPos().nFile); + UnlinkPrunedFiles({oldTip->GetBlockPos().nFile}); + // Verify importmulti RPC returns failure for a key whose creation time is // before the missing block, and success for a key whose creation time is // after. @@ -321,7 +378,8 @@ WalletRescanReserver reserver(wallet.get()); reserver.reserve(); const CBlockIndex *const null_block = nullptr; - const CBlockIndex *stop_block, *failed_block; + const CBlockIndex *stop_block = null_block + 1, + *failed_block = null_block + 1; BOOST_CHECK_EQUAL(wallet->ScanForWalletTransactions( ChainActive().Genesis(), nullptr, reserver, failed_block, stop_block), diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1847,6 +1847,7 @@ const CBlockIndex *pindex = pindexStart; failed_block = nullptr; + stop_block = nullptr; if (pindex) { WalletLogPrintf("Rescan started from block %d...\n", pindex->nHeight);