v29.4-roots.2 · Commit 16: [PATCH 16/21] feat(qt): add per-send RBF override
src/qt/test/wallettests.cpp
Before: src/qt/test/wallettests.cpp · After: src/qt/test/wallettests.cpp
File metadata
index 816d47fed46042d325ba09004ed5e91f7ca7b88c..8e7031719c052206667b9ea99d45f6485f9094cd 100644
Download original patch · Release notes
Diff rows 1–110 of 110. Line numbers refer to the original before/after files.
+ Added− RemovedUnmarked lines are context.
Scroll the code area horizontally to read long lines. The two line-number columns refer to before and after.
src/qt/test/wallettests.cpp
CHANGED
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
#include <qt/walletmodel.h>
|
|
27
27
|
#include <script/solver.h>
|
|
28
28
|
#include <test/util/setup_common.h>
|
|
29
|
+
#include <util/rbf.h>
|
|
29
30
|
#include <validation.h>
|
|
30
31
|
#include <wallet/test/util.h>
|
|
31
32
|
#include <wallet/wallet.h>
|
|
@@ -76,7 +77,7 @@ void ConfirmSend(QString* text = nullptr, QMessageBox::StandardButton confirm_ty
|
|
|
76
77
|
|
|
77
78
|
//! Send coins to address and return txid.
|
|
78
79
|
uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDestination& address, CAmount amount, bool rbf,
|
|
79
|
-
QMessageBox::StandardButton confirm_type = QMessageBox::Yes)
|
|
80
|
+
QMessageBox::StandardButton confirm_type = QMessageBox::Yes, QString* confirmation_text = nullptr)
|
|
80
81
|
{
|
|
81
82
|
QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
|
|
82
83
|
SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
|
|
@@ -90,7 +91,7 @@ uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDe
|
|
|
90
91
|
boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](const uint256& hash, ChangeType status) {
|
|
91
92
|
if (status == CT_NEW) txid = hash;
|
|
92
93
|
}));
|
|
93
|
-
ConfirmSend(/*text=*/nullptr, confirm_type);
|
|
94
|
+
ConfirmSend(confirmation_text, confirm_type);
|
|
94
95
|
bool invoked = QMetaObject::invokeMethod(&sendCoinsDialog, "sendButtonClicked", Q_ARG(bool, false));
|
|
95
96
|
assert(invoked);
|
|
96
97
|
return txid;
|
|
@@ -273,6 +274,8 @@ public:
|
|
|
273
274
|
// QT_QPA_PLATFORM=cocoa build/bin/test_bitcoin-qt # macOS
|
|
274
275
|
void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
|
|
275
276
|
{
|
|
277
|
+
wallet->m_signal_rbf = false;
|
|
278
|
+
|
|
276
279
|
// Create widgets for sending coins and listing transactions.
|
|
277
280
|
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
|
|
278
281
|
MiniGUI mini_gui(node, platformStyle.get());
|
|
@@ -292,19 +295,42 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
|
|
|
292
295
|
// Send two transactions, and verify they are added to transaction list.
|
|
293
296
|
TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
|
|
294
297
|
QCOMPARE(transactionTableModel->rowCount({}), 105);
|
|
295
|
-
uint256 txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false);
|
|
296
|
-
uint256 txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true);
|
|
298
|
+
QCheckBox* rbf_checkbox = sendCoinsDialog.findChild<QCheckBox*>("optInRBF");
|
|
299
|
+
QVERIFY(rbf_checkbox);
|
|
300
|
+
QCOMPARE(rbf_checkbox->text(), "Enable Replace-By-Fee");
|
|
301
|
+
QVERIFY(rbf_checkbox->focusPolicy() != Qt::NoFocus);
|
|
302
|
+
QVERIFY(!rbf_checkbox->isChecked());
|
|
303
|
+
|
|
304
|
+
QString no_rbf_confirmation;
|
|
305
|
+
uint256 txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false, QMessageBox::Yes, &no_rbf_confirmation);
|
|
306
|
+
QString rbf_confirmation;
|
|
307
|
+
uint256 txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true, QMessageBox::Yes, &rbf_confirmation);
|
|
308
|
+
QVERIFY(!SignalsOptInRBF(*wallet->mapWallet.at(txid1).tx));
|
|
309
|
+
QVERIFY(SignalsOptInRBF(*wallet->mapWallet.at(txid2).tx));
|
|
310
|
+
QVERIFY(no_rbf_confirmation.contains("Not signalling Replace-By-Fee, BIP-125."));
|
|
311
|
+
QVERIFY(rbf_confirmation.contains("signals Replace-By-Fee (BIP-125)"));
|
|
312
|
+
|
|
313
|
+
wallet->m_signal_rbf = true;
|
|
314
|
+
SendCoinsDialog default_rbf_dialog(platformStyle.get());
|
|
315
|
+
default_rbf_dialog.setModel(&walletModel);
|
|
316
|
+
QVERIFY(default_rbf_dialog.findChild<QCheckBox*>("optInRBF")->isChecked());
|
|
317
|
+
QString default_on_override_confirmation;
|
|
318
|
+
uint256 txid3 = SendCoins(*wallet.get(), default_rbf_dialog, PKHash(), COIN, /*rbf=*/false, QMessageBox::Yes, &default_on_override_confirmation);
|
|
319
|
+
QVERIFY(!SignalsOptInRBF(*wallet->mapWallet.at(txid3).tx));
|
|
320
|
+
QVERIFY(default_on_override_confirmation.contains("Not signalling Replace-By-Fee, BIP-125."));
|
|
297
321
|
// Transaction table model updates on a QueuedConnection, so process events to ensure it's updated.
|
|
298
322
|
qApp->processEvents();
|
|
299
|
-
QCOMPARE(transactionTableModel->rowCount({}), 107);
|
|
323
|
+
QCOMPARE(transactionTableModel->rowCount({}), 108);
|
|
300
324
|
QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
|
|
301
325
|
QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
|
|
326
|
+
QVERIFY(FindTx(*transactionTableModel, txid3).isValid());
|
|
302
327
|
|
|
303
328
|
// Call bumpfee. Test disabled, canceled, enabled, then failing cases.
|
|
304
329
|
BumpFee(transactionView, txid1, /*expectDisabled=*/true, /*expectError=*/"not BIP 125 replaceable", /*cancel=*/false);
|
|
305
330
|
BumpFee(transactionView, txid2, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/true);
|
|
306
331
|
BumpFee(transactionView, txid2, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/false);
|
|
307
332
|
BumpFee(transactionView, txid2, /*expectDisabled=*/true, /*expectError=*/"already bumped", /*cancel=*/false);
|
|
333
|
+
BumpFee(transactionView, txid3, /*expectDisabled=*/true, /*expectError=*/"not BIP 125 replaceable", /*cancel=*/false);
|
|
308
334
|
|
|
309
335
|
// Check current balance on OverviewPage
|
|
310
336
|
OverviewPage overviewPage(platformStyle.get());
|
|
@@ -443,6 +469,34 @@ void TestGUIWatchOnly(interfaces::Node& node, TestChain100Setup& test)
|
|
|
443
469
|
PartiallySignedTransaction psbt;
|
|
444
470
|
std::string err;
|
|
445
471
|
QVERIFY(DecodeRawPSBT(psbt, MakeByteSpan(*decoded_psbt), err));
|
|
472
|
+
QVERIFY(!SignalsOptInRBF(CTransaction{*psbt.tx}));
|
|
473
|
+
|
|
474
|
+
SendCoinsDialog rbf_psbt_dialog(platformStyle.get());
|
|
475
|
+
rbf_psbt_dialog.setModel(&walletModel);
|
|
476
|
+
rbf_psbt_dialog.getCoinControl()->destChange = GetDestinationForKey(test.coinbaseKey.GetPubKey(), OutputType::LEGACY);
|
|
477
|
+
QTimer rbf_timer;
|
|
478
|
+
rbf_timer.setInterval(500);
|
|
479
|
+
QObject::connect(&rbf_timer, &QTimer::timeout, [&](){
|
|
480
|
+
for (QWidget* widget : QApplication::topLevelWidgets()) {
|
|
481
|
+
if (widget->inherits("QMessageBox") && widget->objectName().compare("psbt_copied_message") == 0) {
|
|
482
|
+
QMessageBox* dialog = qobject_cast<QMessageBox*>(widget);
|
|
483
|
+
QAbstractButton* button = dialog->button(QMessageBox::Discard);
|
|
484
|
+
button->setEnabled(true);
|
|
485
|
+
button->click();
|
|
486
|
+
rbf_timer.stop();
|
|
487
|
+
break;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
});
|
|
491
|
+
rbf_timer.start(500);
|
|
492
|
+
|
|
493
|
+
SendCoins(*wallet.get(), rbf_psbt_dialog, PKHash(), 5 * COIN, /*rbf=*/true, QMessageBox::Save);
|
|
494
|
+
decoded_psbt = DecodeBase64(QApplication::clipboard()->text().toStdString());
|
|
495
|
+
QVERIFY(decoded_psbt);
|
|
496
|
+
psbt = {};
|
|
497
|
+
err.clear();
|
|
498
|
+
QVERIFY(DecodeRawPSBT(psbt, MakeByteSpan(*decoded_psbt), err));
|
|
499
|
+
QVERIFY(SignalsOptInRBF(CTransaction{*psbt.tx}));
|
|
446
500
|
}
|
|
447
501
|
|
|
448
502
|
void TestGUI(interfaces::Node& node)
|