libwallet_api_tests: stop wallet refresh before closing
What changed, and why it matters
This change only touches Monero's internal test code. It makes sure automated wallet tests stop background refresh threads before closing the wallet, likely to prevent flaky or crashing tests. There is no indication this fixes a security vulnerability in the actual Monero wallet software that end users run.
No security action required for end users or operators. Treat as a normal test-stability improvement. If reviewing, confirm the production wallet manager already performs equivalent refresh stopping in closeWallet() or its destructor.
Security signals we found
Background-thread lifecycle management in test teardown
Potential use-after-free or race condition avoided in test harness only
Evidence from the diff
The commit modifies tests/libwallet_api_tests/main.cpp to call pauseRefresh() and stop() on wallet objects before closeWallet(), and adds assertions that wait for a refresh callback condition variable. This is a test-harness hygiene fix: it ensures background refresh threads are quiesced before wallet destruction, avoiding race conditions during test teardown. The diff does not change production wallet code, consensus, networking, or cryptography.
Changed components
tests/libwallet_api_tests/main.cppInspect captured patch +14 / −0
diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp
index 15780b0..c420903 100644
--- a/tests/libwallet_api_tests/main.cpp
+++ b/tests/libwallet_api_tests/main.cpp
@@ -1124,6 +1124,8 @@ TEST_F(WalletTest2, WalletCallBackRefreshedAsync)
ASSERT_TRUE(wallet_src_listener->refresh_triggered);
ASSERT_TRUE(wallet_src->connected());
std::cerr << "TEST: closing wallet...\n";
+ wallet_src->pauseRefresh();
+ wallet_src->stop();
wmgr->closeWallet(wallet_src);
}
@@ -1165,6 +1167,10 @@ TEST_F(WalletTest2, WalletCallbackSent)
ASSERT_TRUE(wallet_src_listener->update_triggered);
std::cout << "** Balance: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl;
ASSERT_TRUE(wallet_src->balance(0) < balance);
+ wallet_src->pauseRefresh();
+ wallet_src->stop();
+ ASSERT_TRUE(wallet_src_listener->cv_refresh.wait_for(lock, wait_for,
+ [wallet_src_listener] { return wallet_src_listener->refresh_triggered; }));
wmgr->closeWallet(wallet_src);
wmgr->closeWallet(wallet_dst);
}
@@ -1212,6 +1218,10 @@ TEST_F(WalletTest2, WalletCallbackReceived)
ASSERT_TRUE(wallet_dst->balance(0) > balance);
+ wallet_dst->pauseRefresh();
+ wallet_dst->stop();
+ ASSERT_TRUE(wallet_dst_listener->cv_refresh.wait_for(lock, wait_for,
+ [&wallet_dst_listener] { return wallet_dst_listener->refresh_triggered; }));
wmgr->closeWallet(wallet_src);
wmgr->closeWallet(wallet_dst);
}
@@ -1241,6 +1251,10 @@ TEST_F(WalletTest2, WalletCallbackNewBlock)
uint64_t bc2 = wallet_src->blockChainHeight();
std::cout << "** Block height: " << bc2 << std::endl;
ASSERT_TRUE(bc2 > bc1);
+ wallet_src->pauseRefresh();
+ wallet_src->stop();
+ ASSERT_TRUE(wallet_listener->cv_refresh.wait_for(lock, wait_for,
+ [&wallet_listener] { return wallet_listener->refresh_triggered; }));
wmgr->closeWallet(wallet_src);
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.