aboutsummaryrefslogtreecommitdiff
path: root/src/qt/walletcontroller.cpp
diff options
context:
space:
mode:
authorHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2023-09-20 22:25:37 +0100
committerHennadii Stepanov <32963518+hebasto@users.noreply.github.com>2023-09-20 22:32:31 +0100
commit1d4846a8443be901b8a5deb0e357481af22838d0 (patch)
tree97798d559e47f142411b5c2d95d7b1a0ee4168e4 /src/qt/walletcontroller.cpp
parent8247a8db6963d2116dc4697a3217d736c197f91d (diff)
parent48aae2cffeb91add75a70ac4d5075c38054452fa (diff)
downloadbitcoin-1d4846a8443be901b8a5deb0e357481af22838d0.tar.xz
Merge bitcoin-core/gui#738: Add menu option to migrate a wallet
48aae2cffeb91add75a70ac4d5075c38054452fa gui: Add File > Migrate Wallet (Andrew Chow) 577be889cd52fc2d896a5f39c66bc2cadb8622e4 gui: Optionally return passphrase after unlocking (Andrew Chow) 5b3a85b4c6ffd1f29a917d4c1af4bff6c0ea2ef5 interfaces, wallet: Expose migrate wallet (Andrew Chow) Pull request description: GUI users need to be able to migrate wallets without going to the RPC console. ACKs for top commit: jarolrod: ACK 48aae2cffeb91add75a70ac4d5075c38054452fa pablomartin4btc: tACK 48aae2cffeb91add75a70ac4d5075c38054452fa hebasto: ACK 48aae2cffeb91add75a70ac4d5075c38054452fa Tree-SHA512: 2d02b1e85e7d6cfbf503f417f150cdaa0c63822942e9a6fe28c0ad3e7f40a957bb01a375c909a60432dc600e84574881aa446c7ec983b56f0bb23f07ef15de54
Diffstat (limited to 'src/qt/walletcontroller.cpp')
-rw-r--r--src/qt/walletcontroller.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp
index 8c8abf0e90..ca2fa2d672 100644
--- a/src/qt/walletcontroller.cpp
+++ b/src/qt/walletcontroller.cpp
@@ -435,3 +435,67 @@ void RestoreWalletActivity::finish()
Q_EMIT finished();
}
+
+void MigrateWalletActivity::migrate(WalletModel* wallet_model)
+{
+ // Warn the user about migration
+ QMessageBox box(m_parent_widget);
+ box.setWindowTitle(tr("Migrate wallet"));
+ box.setText(tr("Are you sure you wish to migrate the wallet <i>%1</i>?").arg(GUIUtil::HtmlEscape(wallet_model->getDisplayName())));
+ 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"
+ "If this wallet contains any watchonly scripts, a new wallet will be created which contains those watchonly scripts.\n"
+ "If this wallet contains any solvable but not watched scripts, a different and new wallet will be created which contains those scripts.\n\n"
+ "The migration process will create a backup of the wallet before migrating. This backup file will be named "
+ "<wallet name>-<timestamp>.legacy.bak and can be found in the directory for this wallet. In the event of "
+ "an incorrect migration, the backup can be restored with the \"Restore Wallet\" functionality."));
+ box.setStandardButtons(QMessageBox::Yes|QMessageBox::Cancel);
+ box.setDefaultButton(QMessageBox::Yes);
+ if (box.exec() != QMessageBox::Yes) return;
+
+ // Get the passphrase if it is encrypted regardless of it is locked or unlocked. We need the passphrase itself.
+ SecureString passphrase;
+ WalletModel::EncryptionStatus enc_status = wallet_model->getEncryptionStatus();
+ if (enc_status == WalletModel::EncryptionStatus::Locked || enc_status == WalletModel::EncryptionStatus::Unlocked) {
+ AskPassphraseDialog dlg(AskPassphraseDialog::Unlock, m_parent_widget, &passphrase);
+ dlg.setModel(wallet_model);
+ dlg.exec();
+ }
+
+ // GUI needs to remove the wallet so that it can actually be unloaded by migration
+ const std::string name = wallet_model->wallet().getWalletName();
+ m_wallet_controller->removeAndDeleteWallet(wallet_model);
+
+ showProgressDialog(tr("Migrate Wallet"), tr("Migrating Wallet <b>%1</b>…").arg(GUIUtil::HtmlEscape(name)));
+
+ QTimer::singleShot(0, worker(), [this, name, passphrase] {
+ auto res{node().walletLoader().migrateWallet(name, passphrase)};
+
+ if (res) {
+ m_success_message = tr("The wallet '%1' was migrated successfully.").arg(GUIUtil::HtmlEscape(res->wallet->getWalletName()));
+ if (res->watchonly_wallet_name) {
+ m_success_message += tr(" Watchonly scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->watchonly_wallet_name.value()));
+ }
+ if (res->solvables_wallet_name) {
+ m_success_message += tr(" Solvable but not watched scripts have been migrated to a new wallet named '%1'.").arg(GUIUtil::HtmlEscape(res->solvables_wallet_name.value()));
+ }
+ m_wallet_model = m_wallet_controller->getOrCreateWallet(std::move(res->wallet));
+ } else {
+ m_error_message = util::ErrorString(res);
+ }
+
+ QTimer::singleShot(0, this, &MigrateWalletActivity::finish);
+ });
+}
+
+void MigrateWalletActivity::finish()
+{
+ if (!m_error_message.empty()) {
+ QMessageBox::critical(m_parent_widget, tr("Migration failed"), QString::fromStdString(m_error_message.translated));
+ } else {
+ QMessageBox::information(m_parent_widget, tr("Migration Successful"), m_success_message);
+ }
+
+ if (m_wallet_model) Q_EMIT migrated(m_wallet_model);
+
+ Q_EMIT finished();
+}