wallet test: Add unit test for wallet scan save_progress option

This commit is contained in:
Ryan Ofsky 2022-06-08 23:05:16 -03:00 committed by w0xlt
parent a89ddfbe22
commit 230a2f4cc3
3 changed files with 29 additions and 8 deletions

View file

@ -123,7 +123,7 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
// Verify ScanForWalletTransactions picks up transactions in both the old // Verify ScanForWalletTransactions picks up transactions in both the old
// and new block files. // and new block files.
{ {
CWallet wallet(m_node.chain.get(), "", m_args, CreateDummyWalletDatabase()); CWallet wallet(m_node.chain.get(), "", m_args, CreateMockWalletDatabase());
{ {
LOCK(wallet.cs_wallet); LOCK(wallet.cs_wallet);
wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS); wallet.SetWalletFlag(WALLET_FLAG_DESCRIPTORS);
@ -131,13 +131,28 @@ BOOST_FIXTURE_TEST_CASE(scan_for_wallet_transactions, TestChain100Setup)
} }
AddKey(wallet, coinbaseKey); AddKey(wallet, coinbaseKey);
WalletRescanReserver reserver(wallet); WalletRescanReserver reserver(wallet);
std::chrono::steady_clock::time_point fake_time;
reserver.setNow([&] { fake_time += 60s; return fake_time; });
reserver.reserve(); reserver.reserve();
CWallet::ScanResult result = wallet.ScanForWalletTransactions(/*start_block=*/oldTip->GetBlockHash(), /*start_height=*/oldTip->nHeight, /*max_height=*/{}, reserver, /*fUpdate=*/false, /*save_progress=*/false);
{
CBlockLocator locator;
BOOST_CHECK(!WalletBatch{wallet.GetDatabase()}.ReadBestBlock(locator));
BOOST_CHECK(locator.IsNull());
}
CWallet::ScanResult result = wallet.ScanForWalletTransactions(/*start_block=*/oldTip->GetBlockHash(), /*start_height=*/oldTip->nHeight, /*max_height=*/{}, reserver, /*fUpdate=*/false, /*save_progress=*/true);
BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS); BOOST_CHECK_EQUAL(result.status, CWallet::ScanResult::SUCCESS);
BOOST_CHECK(result.last_failed_block.IsNull()); BOOST_CHECK(result.last_failed_block.IsNull());
BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash()); BOOST_CHECK_EQUAL(result.last_scanned_block, newTip->GetBlockHash());
BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight); BOOST_CHECK_EQUAL(*result.last_scanned_height, newTip->nHeight);
BOOST_CHECK_EQUAL(GetBalance(wallet).m_mine_immature, 100 * COIN); BOOST_CHECK_EQUAL(GetBalance(wallet).m_mine_immature, 100 * COIN);
{
CBlockLocator locator;
BOOST_CHECK(WalletBatch{wallet.GetDatabase()}.ReadBestBlock(locator));
BOOST_CHECK(!locator.IsNull());
}
} }
// Prune the older block file. // Prune the older block file.

View file

@ -1707,10 +1707,9 @@ int64_t CWallet::RescanFromTime(int64_t startTime, const WalletRescanReserver& r
*/ */
CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_block, int start_height, std::optional<int> max_height, const WalletRescanReserver& reserver, bool fUpdate, const bool save_progress) CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_block, int start_height, std::optional<int> max_height, const WalletRescanReserver& reserver, bool fUpdate, const bool save_progress)
{ {
using Clock = std::chrono::steady_clock;
constexpr auto INTERVAL_TIME{60s}; constexpr auto INTERVAL_TIME{60s};
auto current_time{Clock::now()}; auto current_time{reserver.now()};
auto start_time{Clock::now()}; auto start_time{reserver.now()};
assert(reserver.isReserved()); assert(reserver.isReserved());
@ -1738,9 +1737,9 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
ShowProgress(strprintf("%s " + _("Rescanning…").translated, GetDisplayName()), std::max(1, std::min(99, (int)(m_scanning_progress * 100)))); ShowProgress(strprintf("%s " + _("Rescanning…").translated, GetDisplayName()), std::max(1, std::min(99, (int)(m_scanning_progress * 100))));
} }
bool next_interval = Clock::now() >= current_time + INTERVAL_TIME; bool next_interval = reserver.now() >= current_time + INTERVAL_TIME;
if (next_interval) { if (next_interval) {
current_time = Clock::now(); current_time = reserver.now();
WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", block_height, progress_current); WalletLogPrintf("Still rescanning. At block %d. Progress=%f\n", block_height, progress_current);
} }
@ -1817,7 +1816,7 @@ CWallet::ScanResult CWallet::ScanForWalletTransactions(const uint256& start_bloc
WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height, progress_current); WalletLogPrintf("Rescan interrupted by shutdown request at block %d. Progress=%f\n", block_height, progress_current);
result.status = ScanResult::USER_ABORT; result.status = ScanResult::USER_ABORT;
} else { } else {
auto duration_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(Clock::now() - start_time); auto duration_milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(reserver.now() - start_time);
WalletLogPrintf("Rescan completed in %15dms\n", duration_milliseconds.count()); WalletLogPrintf("Rescan completed in %15dms\n", duration_milliseconds.count());
} }
return result; return result;

View file

@ -896,8 +896,11 @@ void MaybeResendWalletTxs(WalletContext& context);
class WalletRescanReserver class WalletRescanReserver
{ {
private: private:
using Clock = std::chrono::steady_clock;
using NowFn = std::function<Clock::time_point()>;
CWallet& m_wallet; CWallet& m_wallet;
bool m_could_reserve; bool m_could_reserve;
NowFn m_now;
public: public:
explicit WalletRescanReserver(CWallet& w) : m_wallet(w), m_could_reserve(false) {} explicit WalletRescanReserver(CWallet& w) : m_wallet(w), m_could_reserve(false) {}
@ -918,6 +921,10 @@ public:
return (m_could_reserve && m_wallet.fScanningWallet); return (m_could_reserve && m_wallet.fScanningWallet);
} }
Clock::time_point now() const { return m_now ? m_now() : Clock::now(); };
void setNow(NowFn now) { m_now = std::move(now); }
~WalletRescanReserver() ~WalletRescanReserver()
{ {
if (m_could_reserve) { if (m_could_reserve) {