v30.3-roots.1 · Commit 50: [PATCH 50/68] qt: cleanse and release transient sweep cache
src/qt/test/wallettests.cpp
Before: src/qt/test/wallettests.cpp · After: src/qt/test/wallettests.cpp
File metadata
index b861a828c6ba30ad0e392e25f370970c687baf7f..54069ae8c61a7743cdb24b14a53c3e7d589c17ba 100644
Download original patch · Release notes
Diff rows 1–62 of 62. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. Before is on the left; after is on the right. Unified view fits narrow screens more easily.
src/qt/test/wallettests.cpp
CHANGED
|
@@ -29,6 +29,7 @@
|
|
| 29 |
#include <qt/transactionview.h>
|
| 30 |
#include <qt/walletmodel.h>
|
| 31 |
#include <script/solver.h>
|
|
|
|
| 32 |
#include <test/util/setup_common.h>
|
| 33 |
#include <util/rbf.h>
|
| 34 |
#include <validation.h>
|
|
@@ -71,6 +72,12 @@ using wallet::WalletContext;
|
|
| 71 |
using wallet::WalletDescriptor;
|
| 72 |
using wallet::WalletRescanReserver;
|
| 73 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 74 |
namespace
|
| 75 |
{
|
| 76 |
class LogCapture
|
|
@@ -312,6 +319,19 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
|
|
| 312 |
|
| 313 |
// Verify the guarded sweep dialog contract and asynchronous error path.
|
| 314 |
SweepDialog sweep_dialog(&walletModel);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 315 |
QLineEdit* sweep_key = sweep_dialog.findChild<QLineEdit*>("sweepPrivateKey");
|
| 316 |
QLineEdit* sweep_destination = sweep_dialog.findChild<QLineEdit*>("sweepDestination");
|
| 317 |
QPushButton* sweep_preview = sweep_dialog.findChild<QPushButton*>("sweepPreview");
|
|
@@ -356,6 +376,8 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
|
|
| 356 |
QVERIFY(!sweep_key->isEnabled());
|
| 357 |
QVERIFY(sweep_key->text().isEmpty());
|
| 358 |
QTRY_VERIFY(sweep_key->isEnabled());
|
|
|
|
|
|
|
| 359 |
QVERIFY(!sweep_result->text().contains(sweep_sentinel));
|
| 360 |
QVERIFY(!QString::fromStdString(sweep_logs.output).contains(sweep_sentinel));
|
| 361 |
|
|
@@ -366,6 +388,8 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
|
|
| 366 |
// A competing wallet update must discard the transient key and preview
|
| 367 |
// immediately, rather than relying on broadcast-time stale detection.
|
| 368 |
walletModel.updateTransaction();
|
|
|
|
|
|
|
| 369 |
QVERIFY(sweep_key->isEnabled());
|
| 370 |
QVERIFY(sweep_key->text().isEmpty());
|
| 371 |
QVERIFY(!sweep_broadcast->isEnabled());
|
|
@@ -375,6 +399,8 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
|
|
| 375 |
QVERIFY(!sweep_broadcast->isEnabled());
|
| 376 |
sweep_dialog.reject();
|
| 377 |
QVERIFY(sweep_key->text().isEmpty());
|
|
|
|
|
|
|
| 378 |
|
| 379 |
const auto settings_contain_sentinel = [&] {
|
| 380 |
QSettings settings;
|
|
|
|
| 29 |
#include <qt/transactionview.h>
|
| 30 |
#include <qt/walletmodel.h>
|
| 31 |
#include <script/solver.h>
|
| 32 |
+
#include <support/lockedpool.h>
|
| 33 |
#include <test/util/setup_common.h>
|
| 34 |
#include <util/rbf.h>
|
| 35 |
#include <validation.h>
|
|
|
|
| 72 |
using wallet::WalletDescriptor;
|
| 73 |
using wallet::WalletRescanReserver;
|
| 74 |
|
| 75 |
+
struct SweepDialogTestAccess
|
| 76 |
+
{
|
| 77 |
+
static SecureString& Cache(SweepDialog& dialog) { return dialog.m_private_key_cache; }
|
| 78 |
+
static void ClearCache(SweepDialog& dialog) { dialog.clearPrivateKeyCache(); }
|
| 79 |
+
};
|
| 80 |
+
|
| 81 |
namespace
|
| 82 |
{
|
| 83 |
class LogCapture
|
|
|
|
| 319 |
|
| 320 |
// Verify the guarded sweep dialog contract and asynchronous error path.
|
| 321 |
SweepDialog sweep_dialog(&walletModel);
|
| 322 |
+
auto& sweep_cache{SweepDialogTestAccess::Cache(sweep_dialog)};
|
| 323 |
+
// Disposal must release locked storage while the dialog stays alive;
|
| 324 |
+
// observe allocator accounting rather than dereferencing freed memory.
|
| 325 |
+
const auto locked_bytes_before{LockedPoolManager::Instance().stats().used};
|
| 326 |
+
sweep_cache.assign(52, 's');
|
| 327 |
+
QVERIFY(LockedPoolManager::Instance().stats().used > locked_bytes_before);
|
| 328 |
+
SweepDialogTestAccess::ClearCache(sweep_dialog);
|
| 329 |
+
QVERIFY(sweep_cache.empty());
|
| 330 |
+
QCOMPARE(LockedPoolManager::Instance().stats().used, locked_bytes_before);
|
| 331 |
+
sweep_cache.assign(4, 's');
|
| 332 |
+
SweepDialogTestAccess::ClearCache(sweep_dialog);
|
| 333 |
+
QVERIFY(sweep_cache.empty());
|
| 334 |
+
QCOMPARE(LockedPoolManager::Instance().stats().used, locked_bytes_before);
|
| 335 |
QLineEdit* sweep_key = sweep_dialog.findChild<QLineEdit*>("sweepPrivateKey");
|
| 336 |
QLineEdit* sweep_destination = sweep_dialog.findChild<QLineEdit*>("sweepDestination");
|
| 337 |
QPushButton* sweep_preview = sweep_dialog.findChild<QPushButton*>("sweepPreview");
|
|
|
|
| 376 |
QVERIFY(!sweep_key->isEnabled());
|
| 377 |
QVERIFY(sweep_key->text().isEmpty());
|
| 378 |
QTRY_VERIFY(sweep_key->isEnabled());
|
| 379 |
+
QVERIFY(sweep_cache.empty());
|
| 380 |
+
QCOMPARE(sweep_cache.capacity(), SecureString{}.capacity());
|
| 381 |
QVERIFY(!sweep_result->text().contains(sweep_sentinel));
|
| 382 |
QVERIFY(!QString::fromStdString(sweep_logs.output).contains(sweep_sentinel));
|
| 383 |
|
|
|
|
| 388 |
// A competing wallet update must discard the transient key and preview
|
| 389 |
// immediately, rather than relying on broadcast-time stale detection.
|
| 390 |
walletModel.updateTransaction();
|
| 391 |
+
QVERIFY(sweep_cache.empty());
|
| 392 |
+
QCOMPARE(sweep_cache.capacity(), SecureString{}.capacity());
|
| 393 |
QVERIFY(sweep_key->isEnabled());
|
| 394 |
QVERIFY(sweep_key->text().isEmpty());
|
| 395 |
QVERIFY(!sweep_broadcast->isEnabled());
|
|
|
|
| 399 |
QVERIFY(!sweep_broadcast->isEnabled());
|
| 400 |
sweep_dialog.reject();
|
| 401 |
QVERIFY(sweep_key->text().isEmpty());
|
| 402 |
+
QVERIFY(sweep_cache.empty());
|
| 403 |
+
QCOMPARE(sweep_cache.capacity(), SecureString{}.capacity());
|
| 404 |
|
| 405 |
const auto settings_contain_sentinel = [&] {
|
| 406 |
QSettings settings;
|