Skip to content

Commit f1ea58f

Browse files
committed
gui: Use wallet name for wallet migration rather than WalletModel
To prepare for migrating wallets that are not loaded, when migration occurs in the GUI, it should not rely on a WalletModel existing.
1 parent 3eb67dc commit f1ea58f

File tree

5 files changed

+40
-22
lines changed

5 files changed

+40
-22
lines changed

src/qt/askpassphrasedialog.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ AskPassphraseDialog::AskPassphraseDialog(Mode _mode, QWidget *parent, SecureStri
4444
ui->passEdit1->hide();
4545
setWindowTitle(tr("Encrypt wallet"));
4646
break;
47+
case UnlockMigration:
4748
case Unlock: // Ask passphrase
4849
ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
4950
ui->passLabel2->hide();
@@ -80,7 +81,7 @@ void AskPassphraseDialog::setModel(WalletModel *_model)
8081
void AskPassphraseDialog::accept()
8182
{
8283
SecureString oldpass, newpass1, newpass2;
83-
if (!model && mode != Encrypt)
84+
if (!model && mode != Encrypt && mode != UnlockMigration)
8485
return;
8586
oldpass.reserve(MAX_PASSPHRASE_SIZE);
8687
newpass1.reserve(MAX_PASSPHRASE_SIZE);
@@ -181,6 +182,10 @@ void AskPassphraseDialog::accept()
181182
QMessageBox::critical(this, tr("Wallet unlock failed"), e.what());
182183
}
183184
break;
185+
case UnlockMigration:
186+
Assume(m_passphrase_out)->assign(oldpass);
187+
QDialog::accept();
188+
break;
184189
case ChangePass:
185190
if(newpass1 == newpass2)
186191
{
@@ -224,6 +229,7 @@ void AskPassphraseDialog::textChanged()
224229
case Encrypt: // New passphrase x2
225230
acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
226231
break;
232+
case UnlockMigration:
227233
case Unlock: // Old passphrase x1
228234
acceptable = !ui->passEdit1->text().isEmpty();
229235
break;

src/qt/askpassphrasedialog.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class AskPassphraseDialog : public QDialog
2626
Encrypt, /**< Ask passphrase twice and encrypt */
2727
Unlock, /**< Ask passphrase and unlock */
2828
ChangePass, /**< Ask old passphrase + new passphrase twice */
29+
UnlockMigration, // Ask passphrase for unlocking during migration
2930
};
3031

3132
explicit AskPassphraseDialog(Mode mode, QWidget *parent, SecureString* passphrase_out = nullptr);

src/qt/bitcoingui.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ void BitcoinGUI::createActions()
459459
connect(m_migrate_wallet_action, &QAction::triggered, [this] {
460460
auto activity = new MigrateWalletActivity(m_wallet_controller, this);
461461
connect(activity, &MigrateWalletActivity::migrated, this, &BitcoinGUI::setCurrentWallet);
462-
activity->migrate(walletFrame->currentWalletModel());
462+
activity->migrate(walletFrame->currentWalletModel()->wallet().getWalletName());
463463
});
464464
connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::setPrivacy);
465465
connect(m_mask_values_action, &QAction::toggled, this, &BitcoinGUI::enableHistoryAction);

src/qt/walletcontroller.cpp

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,15 @@ WalletModel* WalletController::getOrCreateWallet(std::unique_ptr<interfaces::Wal
171171
return wallet_model;
172172
}
173173

174+
WalletModel* WalletController::getWallet(const std::string& name)
175+
{
176+
auto it = std::find_if(m_wallets.begin(), m_wallets.end(),
177+
[&name](WalletModel* model) {
178+
return name == model->wallet().getWalletName();
179+
});
180+
return it == m_wallets.end() ? nullptr : *it;
181+
}
182+
174183
void WalletController::removeAndDeleteWallet(WalletModel* wallet_model)
175184
{
176185
// Unregister wallet model.
@@ -436,47 +445,50 @@ void RestoreWalletActivity::finish()
436445
Q_EMIT finished();
437446
}
438447

439-
void MigrateWalletActivity::migrate(WalletModel* wallet_model)
448+
void MigrateWalletActivity::migrate(const std::string& name)
440449
{
441450
// Warn the user about migration
442451
QMessageBox box(m_parent_widget);
443452
box.setWindowTitle(tr("Migrate wallet"));
444-
box.setText(tr("Are you sure you wish to migrate the wallet <i>%1</i>?").arg(GUIUtil::HtmlEscape(wallet_model->getDisplayName())));
453+
box.setText(tr("Are you sure you wish to migrate the wallet <i>%1</i>?").arg(GUIUtil::HtmlEscape(GUIUtil::WalletDisplayName(name))));
445454
box.setInformativeText(tr("Migrating the wallet will convert this wallet to one or more descriptor wallets. A new wallet backup will need to be made.\n"
446455
"If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts.\n"
447456
"If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts.\n\n"
448457
"The migration process will create a backup of the wallet before migrating. This backup file will be named "
449458
"<wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of "
450-
"an incorrect migration, the backup can be restored with the \"Restore Wallet\" functionality."));
451-
box.setStandardButtons(QMessageBox::Yes|QMessageBox::Cancel);
452-
box.setDefaultButton(QMessageBox::Yes);
453-
if (box.exec() != QMessageBox::Yes) return;
459+
"an incorrect migration, the backup can be restored with the \"Restore Wallet\" functionality.\n\n"
460+
"If your wallet is encrypted, please provide the passphrase now as by choosing \"Yes, encrypted\"."));
461+
QPushButton* yes_enc_button = box.addButton(tr("Yes, encrypted"), QMessageBox::YesRole);
462+
QPushButton* yes_button = box.addButton(QMessageBox::Yes);
463+
QPushButton* cancel_button = box.addButton(QMessageBox::Cancel);
464+
box.setDefaultButton(yes_button);
465+
box.exec();
466+
if (!box.clickedButton() || box.clickedButton() == (QAbstractButton*)cancel_button) return;
454467

455-
// Get the passphrase if it is encrypted regardless of it is locked or unlocked. We need the passphrase itself.
456468
SecureString passphrase;
457-
WalletModel::EncryptionStatus enc_status = wallet_model->getEncryptionStatus();
458-
if (enc_status == WalletModel::EncryptionStatus::Locked || enc_status == WalletModel::EncryptionStatus::Unlocked) {
459-
AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, m_parent_widget, &passphrase);
460-
dlg.setModel(wallet_model);
461-
dlg.exec();
469+
if (box.clickedButton() == (QAbstractButton*)yes_enc_button) {
470+
// Get the passphrase for the wallet
471+
AskPassphraseDialog dlg(AskPassphraseDialog::UnlockMigration, m_parent_widget, &passphrase);
472+
if (dlg.exec() == QDialog::Rejected) return;
462473
}
463474

464475
// GUI needs to remove the wallet so that it can actually be unloaded by migration
465-
const std::string name = wallet_model->wallet().getWalletName();
466-
m_wallet_controller->removeAndDeleteWallet(wallet_model);
476+
if (WalletModel* wallet = m_wallet_controller->getWallet(name)) {
477+
m_wallet_controller->removeAndDeleteWallet(wallet);
478+
};
467479

468480
showProgressDialog(tr("Migrate Wallet"), tr("Migrating Wallet <b>%1</b>…").arg(GUIUtil::HtmlEscape(name)));
469481

470482
QTimer::singleShot(0, worker(), [this, name, passphrase] {
471483
auto res{node().walletLoader().migrateWallet(name, passphrase)};
472484

473485
if (res) {
474-
m_success_message = tr("The wallet '%1' was migrated successfully.").arg(GUIUtil::HtmlEscape(res->wallet->getWalletName()));
486+
m_success_message = tr("The wallet '%1' was migrated successfully.").arg(GUIUtil::HtmlEscape(GUIUtil::WalletDisplayName(res->wallet->getWalletName())));
475487
if (res->watchonly_wallet_name) {
476-
m_success_message += QChar(' ') + tr("Watchonly scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->watchonly_wallet_name.value()));
488+
m_success_message += QChar(' ') + tr("Watchonly scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(GUIUtil::WalletDisplayName(res->watchonly_wallet_name.value())));
477489
}
478490
if (res->solvables_wallet_name) {
479-
m_success_message += QChar(' ') + tr("Solvable but not watched scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->solvables_wallet_name.value()));
491+
m_success_message += QChar(' ') + tr("Solvable but not watched scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(GUIUtil::WalletDisplayName(res->solvables_wallet_name.value())));
480492
}
481493
m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(res->wallet));
482494
} else {

src/qt/walletcontroller.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class WalletController : public QObject
5858
~WalletController();
5959

6060
WalletModel* getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
61+
WalletModel* getWallet(const std::string& name);
6162

6263
//! Returns all wallet names in the wallet dir mapped to whether the wallet
6364
//! is loaded.
@@ -66,8 +67,6 @@ class WalletController : public QObject
6667
void closeWallet(WalletModel* wallet_model, QWidget* parent = nullptr);
6768
void closeAllWallets(QWidget* parent = nullptr);
6869

69-
void migrateWallet(WalletModel* wallet_model, QWidget* parent = nullptr);
70-
7170
Q_SIGNALS:
7271
void walletAdded(WalletModel* wallet_model);
7372
void walletRemoved(WalletModel* wallet_model);
@@ -186,7 +185,7 @@ class MigrateWalletActivity : public WalletControllerActivity
186185
public:
187186
MigrateWalletActivity(WalletController* wallet_controller, QWidget* parent) : WalletControllerActivity(wallet_controller, parent) {}
188187

189-
void migrate(WalletModel* wallet_model);
188+
void migrate(const std::string& path);
190189

191190
Q_SIGNALS:
192191
void migrated(WalletModel* wallet_model);

0 commit comments

Comments
 (0)