Skip to content
Bitcoin Roots

v30.3-roots.1 · Commit 16: [PATCH 16/68] 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 5e65dcca318d978d10c58605669197dee236daaa..a477110f9ae62f0d0b236850d143289323e9ba75 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. Before is on the left; after is on the right. Unified view fits narrow screens more easily.

src/qt/test/wallettests.cpp CHANGED
@@ -26,6 +26,7 @@
26
  #include <qt/walletmodel.h>
27
  #include <script/solver.h>
28
  #include <test/util/setup_common.h>
 
29
  #include <validation.h>
30
  #include <wallet/test/util.h>
31
  #include <wallet/wallet.h>
@@ -76,7 +77,7 @@ void ConfirmSend(QString* text = nullptr, QMessageBox::StandardButton confirm_ty
76
 
77
  //! Send coins to address and return txid.
78
  Txid SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDestination& address, CAmount amount, bool rbf,
79
- QMessageBox::StandardButton confirm_type = QMessageBox::Yes)
80
  {
81
  QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
82
  SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
@@ -90,7 +91,7 @@ Txid SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDesti
90
  boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](const Txid& hash, ChangeType status) {
91
  if (status == CT_NEW) txid = hash;
92
  }));
93
- ConfirmSend(/*text=*/nullptr, confirm_type);
94
  bool invoked = QMetaObject::invokeMethod(&sendCoinsDialog, "sendButtonClicked", Q_ARG(bool, false));
95
  assert(invoked);
96
  return txid;
@@ -265,6 +266,8 @@ public:
265
  // QT_QPA_PLATFORM=cocoa build/bin/test_bitcoin-qt # macOS
266
  void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
267
  {
 
 
268
  // Create widgets for sending coins and listing transactions.
269
  std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
270
  MiniGUI mini_gui(node, platformStyle.get());
@@ -284,19 +287,42 @@ void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
284
  // Send two transactions, and verify they are added to transaction list.
285
  TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
286
  QCOMPARE(transactionTableModel->rowCount({}), 105);
287
- Txid txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false);
288
- Txid txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
  // Transaction table model updates on a QueuedConnection, so process events to ensure it's updated.
290
  qApp->processEvents();
291
- QCOMPARE(transactionTableModel->rowCount({}), 107);
292
  QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
293
  QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
 
294
 
295
  // Call bumpfee. Test canceled fullrbf bump, canceled bip-125-rbf bump, passing bump, and then failing bump.
296
  BumpFee(transactionView, txid1, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/true);
297
  BumpFee(transactionView, txid2, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/true);
298
  BumpFee(transactionView, txid2, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/false);
299
  BumpFee(transactionView, txid2, /*expectDisabled=*/true, /*expectError=*/"already bumped", /*cancel=*/false);
 
300
 
301
  // Check current balance on OverviewPage
302
  OverviewPage overviewPage(platformStyle.get());
@@ -435,6 +461,34 @@ void TestGUIWatchOnly(interfaces::Node& node, TestChain100Setup& test)
435
  PartiallySignedTransaction psbt;
436
  std::string err;
437
  QVERIFY(DecodeRawPSBT(psbt, MakeByteSpan(*decoded_psbt), err));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
438
  }
439
 
440
  void TestGUI(interfaces::Node& node)
 
26
  #include <qt/walletmodel.h>
27
  #include <script/solver.h>
28
  #include <test/util/setup_common.h>
29
+ #include <util/rbf.h>
30
  #include <validation.h>
31
  #include <wallet/test/util.h>
32
  #include <wallet/wallet.h>
 
77
 
78
  //! Send coins to address and return txid.
79
  Txid SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CTxDestination& address, CAmount amount, bool rbf,
80
+ QMessageBox::StandardButton confirm_type = QMessageBox::Yes, QString* confirmation_text = nullptr)
81
  {
82
  QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
83
  SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
 
91
  boost::signals2::scoped_connection c(wallet.NotifyTransactionChanged.connect([&txid](const Txid& hash, ChangeType status) {
92
  if (status == CT_NEW) txid = hash;
93
  }));
94
+ ConfirmSend(confirmation_text, confirm_type);
95
  bool invoked = QMetaObject::invokeMethod(&sendCoinsDialog, "sendButtonClicked", Q_ARG(bool, false));
96
  assert(invoked);
97
  return txid;
 
266
  // QT_QPA_PLATFORM=cocoa build/bin/test_bitcoin-qt # macOS
267
  void TestGUI(interfaces::Node& node, const std::shared_ptr<CWallet>& wallet)
268
  {
269
+ wallet->m_signal_rbf = false;
270
+
271
  // Create widgets for sending coins and listing transactions.
272
  std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
273
  MiniGUI mini_gui(node, platformStyle.get());
 
287
  // Send two transactions, and verify they are added to transaction list.
288
  TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
289
  QCOMPARE(transactionTableModel->rowCount({}), 105);
290
+ QCheckBox* rbf_checkbox = sendCoinsDialog.findChild<QCheckBox*>("optInRBF");
291
+ QVERIFY(rbf_checkbox);
292
+ QCOMPARE(rbf_checkbox->text(), "Enable Replace-By-Fee");
293
+ QVERIFY(rbf_checkbox->focusPolicy() != Qt::NoFocus);
294
+ QVERIFY(!rbf_checkbox->isChecked());
295
+
296
+ QString no_rbf_confirmation;
297
+ Txid txid1 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 5 * COIN, /*rbf=*/false, QMessageBox::Yes, &no_rbf_confirmation);
298
+ QString rbf_confirmation;
299
+ Txid txid2 = SendCoins(*wallet.get(), sendCoinsDialog, PKHash(), 10 * COIN, /*rbf=*/true, QMessageBox::Yes, &rbf_confirmation);
300
+ QVERIFY(!SignalsOptInRBF(*wallet->mapWallet.at(txid1).tx));
301
+ QVERIFY(SignalsOptInRBF(*wallet->mapWallet.at(txid2).tx));
302
+ QVERIFY(no_rbf_confirmation.contains("Not signalling Replace-By-Fee, BIP-125."));
303
+ QVERIFY(rbf_confirmation.contains("signals Replace-By-Fee (BIP-125)"));
304
+
305
+ wallet->m_signal_rbf = true;
306
+ SendCoinsDialog default_rbf_dialog(platformStyle.get());
307
+ default_rbf_dialog.setModel(&walletModel);
308
+ QVERIFY(default_rbf_dialog.findChild<QCheckBox*>("optInRBF")->isChecked());
309
+ QString default_on_override_confirmation;
310
+ Txid txid3 = SendCoins(*wallet.get(), default_rbf_dialog, PKHash(), COIN, /*rbf=*/false, QMessageBox::Yes, &default_on_override_confirmation);
311
+ QVERIFY(!SignalsOptInRBF(*wallet->mapWallet.at(txid3).tx));
312
+ QVERIFY(default_on_override_confirmation.contains("Not signalling Replace-By-Fee, BIP-125."));
313
  // Transaction table model updates on a QueuedConnection, so process events to ensure it's updated.
314
  qApp->processEvents();
315
+ QCOMPARE(transactionTableModel->rowCount({}), 108);
316
  QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
317
  QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
318
+ QVERIFY(FindTx(*transactionTableModel, txid3).isValid());
319
 
320
  // Call bumpfee. Test canceled fullrbf bump, canceled bip-125-rbf bump, passing bump, and then failing bump.
321
  BumpFee(transactionView, txid1, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/true);
322
  BumpFee(transactionView, txid2, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/true);
323
  BumpFee(transactionView, txid2, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/false);
324
  BumpFee(transactionView, txid2, /*expectDisabled=*/true, /*expectError=*/"already bumped", /*cancel=*/false);
325
+ BumpFee(transactionView, txid3, /*expectDisabled=*/false, /*expectError=*/{}, /*cancel=*/true);
326
 
327
  // Check current balance on OverviewPage
328
  OverviewPage overviewPage(platformStyle.get());
 
461
  PartiallySignedTransaction psbt;
462
  std::string err;
463
  QVERIFY(DecodeRawPSBT(psbt, MakeByteSpan(*decoded_psbt), err));
464
+ QVERIFY(!SignalsOptInRBF(CTransaction{*psbt.tx}));
465
+
466
+ SendCoinsDialog rbf_psbt_dialog(platformStyle.get());
467
+ rbf_psbt_dialog.setModel(&walletModel);
468
+ rbf_psbt_dialog.getCoinControl()->destChange = PKHash{test.coinbaseKey.GetPubKey()};
469
+ QTimer rbf_timer;
470
+ rbf_timer.setInterval(500);
471
+ QObject::connect(&rbf_timer, &QTimer::timeout, [&](){
472
+ for (QWidget* widget : QApplication::topLevelWidgets()) {
473
+ if (widget->inherits("QMessageBox") && widget->objectName().compare("psbt_copied_message") == 0) {
474
+ QMessageBox* dialog = qobject_cast<QMessageBox*>(widget);
475
+ QAbstractButton* button = dialog->button(QMessageBox::Discard);
476
+ button->setEnabled(true);
477
+ button->click();
478
+ rbf_timer.stop();
479
+ break;
480
+ }
481
+ }
482
+ });
483
+ rbf_timer.start(500);
484
+
485
+ SendCoins(*wallet.get(), rbf_psbt_dialog, PKHash(), 5 * COIN, /*rbf=*/true, QMessageBox::Save);
486
+ decoded_psbt = DecodeBase64(QApplication::clipboard()->text().toStdString());
487
+ QVERIFY(decoded_psbt);
488
+ psbt = {};
489
+ err.clear();
490
+ QVERIFY(DecodeRawPSBT(psbt, MakeByteSpan(*decoded_psbt), err));
491
+ QVERIFY(SignalsOptInRBF(CTransaction{*psbt.tx}));
492
  }
493
 
494
  void TestGUI(interfaces::Node& node)