-
Notifications
You must be signed in to change notification settings - Fork 273
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Wallet Restore in the GUI #471
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
I am going to do a full tested review in some time.
It would help to add the screenshots of the difference between the master branch and the PR branch in the description.
In the meantime, here's one nit I caught.
985c64e
to
f202ddb
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested Successfully on Ubuntu 20.04
I was able to successfully load the wallet from the wallet.dat file using the menu option introduced in this PR.
Master | PR |
---|---|
Tested that error message is working perfectly using the following patch:
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -357,7 +357,7 @@ std::shared_ptr<CWallet> RestoreWallet(WalletContext& context, const std::string
{
const fs::path wallet_path = fsbridge::AbsPathJoin(GetWalletDir(), fs::u8path(wallet_name));
- if (fs::exists(wallet_path) || !TryCreateDirectories(wallet_path)) {
+ if (!fs::exists(wallet_path) || !TryCreateDirectories(wallet_path)) {
error = Untranslated(strprintf("Failed to create database path '%s'. Database already exists.", fs::PathToString(wallet_path)));
status = DatabaseStatus::FAILED_ALREADY_EXISTS;
return nullptr;
Tested warning message using the following patch
--- a/src/wallet/wallet.cpp
+++ b/src/wallet/wallet.cpp
@@ -85,7 +85,7 @@ static void UpdateWalletSetting(interfaces::Chain& chain,
std::vector<bilingual_str>& warnings)
{
if (!load_on_startup) return;
- if (load_on_startup.value() && !AddWalletSetting(chain, wallet_name)) {
+ if (load_on_startup.value() && AddWalletSetting(chain, wallet_name)) {
warnings.emplace_back(Untranslated("Wallet load on startup setting could not be updated, so wallet may not be loaded next node startup."));
} else if (!load_on_startup.value() && !RemoveWalletSetting(chain, wallet_name)) {
Screenshot of warning message:
There are some minor corrections and suggestions I found that might help improve this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
concept ack
Concept ACK. @w0xlt |
32b6e3e
to
a047c1a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes since my last review:
- Addressed following suggestions: 1, 2
- Added translator comment for strings displayed on the user’s side.
The translator comment looks good and helps significantly clarify the meaning and purpose of each string. I have some suggestions for the translator comment, though, that you might consider, to improve upon these comments.
a047c1a
to
b5ad1bd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes since my last review:
- Translator comments are updated according to this suggestion.
I think this PR is functionally correct now. However, there are some formatting corrections I would like to suggest. (p.s. Sorry, I forgot to check formatting in my earlier reviews of this PR.)
To automatically correct formatting, you can use the following line of code:
git diff -U0 HEAD~1.. | ./contrib/devtools/clang-format-diff.py -p1 -i -v
The differences I observed after running the above statement:
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index f21c5048f..363b618d8 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -442,10 +442,10 @@ void BitcoinGUI::createActions()
});
connect(m_restore_wallet_action, &QAction::triggered, [this] {
QString backupFile = GUIUtil::getOpenFileName(this,
- //: The title for Restore Wallet File Windows
- tr("Load Wallet Backup"), QString(),
- //: The file extension for Restore Wallet File Windows
- tr("Wallet Data File (*.dat)"), nullptr);
+ //: The title for Restore Wallet File Windows
+ tr("Load Wallet Backup"), QString(),
+ //: The file extension for Restore Wallet File Windows
+ tr("Wallet Data File (*.dat)"), nullptr);
if (backupFile.isEmpty()) return;
bool walletNameOk;
diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp
index 38095ee74..81822d5e5 100644
--- a/src/qt/walletcontroller.cpp
+++ b/src/qt/walletcontroller.cpp
@@ -381,8 +381,7 @@ void RestoreWalletActivity::restore(const std::string& backup_file, const std::s
tr("Restore Wallet"),
/*: Descriptive text of the restore wallets progress window which indicates to
the user that wallets are currently being restored.*/
- tr("Restoring Wallet <b>%1</b>…").arg(name.toHtmlEscaped())
- );
+ tr("Restoring Wallet <b>%1</b>…").arg(name.toHtmlEscaped()));
QTimer::singleShot(0, worker(), [this, backup_file, wallet_name] {
std::unique_ptr<interfaces::Wallet> wallet = node().walletClient().restoreWallet(backup_file, wallet_name, m_error_message, m_warning_message);
@@ -410,4 +409,3 @@ void RestoreWalletActivity::finish()
Q_EMIT finished();
}
b5ad1bd
to
e0b6d19
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This duplicates new RPC functionality. Please first abstract the RPC code so GUI can share it instead of duplicating it.
Also, I think it would be better to handle error conditions nicer before exposing this to the GUI. For example, we should detect if the wallet is already present and error if so. If an error occurs, we should delete the copy-destination file we made.
32b9eba
to
d021bf9
Compare
d021bf9 modifies the A separate PR (bitcoin/bitcoin#23721) has been opened in the Bitcoin repository to change files that are not GUI related, as suggested in #471 (comment) |
Will test soon. Concept ACK |
…ogic to the wallet section 62fa61f refactor: remove the wallet folder if the restore fails (w0xlt) abbb7ec refactor: Move restorewallet() RPC logic to the wallet section (w0xlt) 4807f73 refactor: Implement restorewallet() logic in the wallet section (w0xlt) Pull request description: Currently `restorewallet()` logic is written in the RPC layer and it can´t be reused by GUI. So it moves this to the wallet section and then, GUI can access it. This is necessary to implement the "Restore Wallet" menu item in the GUI (which is already implemented in #471 ). This commit also simplifies error handling and adds a new behavior: if the restore fails, the invalid wallet folder is removed. ACKs for top commit: achow101: ACK 62fa61f shaavan: crACK 62fa61f Tree-SHA512: 7ccfbad5943f38616ba0c2dd443c97a4b5bc1f6612dbf5a9e7a0263100aba36671fae929a2e7688442667be394645f44484af137a4802f204a33c4689eb27c39
…the wallet section 62fa61f refactor: remove the wallet folder if the restore fails (w0xlt) abbb7ec refactor: Move restorewallet() RPC logic to the wallet section (w0xlt) 4807f73 refactor: Implement restorewallet() logic in the wallet section (w0xlt) Pull request description: Currently `restorewallet()` logic is written in the RPC layer and it can´t be reused by GUI. So it moves this to the wallet section and then, GUI can access it. This is necessary to implement the "Restore Wallet" menu item in the GUI (which is already implemented in bitcoin-core/gui#471 ). This commit also simplifies error handling and adds a new behavior: if the restore fails, the invalid wallet folder is removed. ACKs for top commit: achow101: ACK 62fa61f shaavan: crACK 62fa61f Tree-SHA512: 7ccfbad5943f38616ba0c2dd443c97a4b5bc1f6612dbf5a9e7a0263100aba36671fae929a2e7688442667be394645f44484af137a4802f204a33c4689eb27c39
d021bf9
to
e82a654
Compare
Rebased. CI error is unrelated. |
CI job has been restarted. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tested and code reviewed e681634
Found the following issue:
The restored
signal is being processed prior to the full execution of addWallet
(walletAdded
signal slot), which causes a mismatch where the GUI shows the frame of the recently loaded wallet without updating the wallet selector (the top right combo box) nor the window title.
It seems to be happening because QT lowers the addWallet
execution priority while is creating the new WalletView
object.
It can be fixed by making the restored
signal connection a Qt::QueuedConnection
type.
In other words, patch:
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
--- a/src/qt/bitcoingui.cpp (revision 34dff82864965126e35876c02c8158e06d652013)
+++ b/src/qt/bitcoingui.cpp (date 1654004973424)
@@ -433,7 +433,7 @@
if (!walletNameOk || walletName.isEmpty()) return;
auto activity = new RestoreWalletActivity(m_wallet_controller, this);
- connect(activity, &RestoreWalletActivity::restored, this, &BitcoinGUI::setCurrentWallet);
+ connect(activity, &RestoreWalletActivity::restored, this, &BitcoinGUI::setCurrentWallet, Qt::QueuedConnection);
auto backup_file_path = fs::PathFromString(backup_file.toStdString());
activity->restore(backup_file_path, walletName.toStdString());
@furszy Thanks for the sugestion. After applying it, the GUI now switches to the wallet as soon as it finishes restoring it. |
CI error seems unrelated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code review + tested ACK c99f58a
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsNo conflicts as of last run. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approach ACK c99f58a.
Suggesting to apply clang-format-diff.py
to your commit(s).
Is it better to combine actions in a menu group:
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -473,12 +473,13 @@ void BitcoinGUI::createMenuBar()
{
file->addAction(m_create_wallet_action);
file->addAction(m_open_wallet_action);
- file->addAction(m_restore_wallet_action);
file->addAction(m_close_wallet_action);
file->addAction(m_close_all_wallets_action);
file->addSeparator();
- file->addAction(openAction);
file->addAction(backupWalletAction);
+ file->addAction(m_restore_wallet_action);
+ file->addSeparator();
+ file->addAction(openAction);
file->addAction(signMessageAction);
file->addAction(verifyMessageAction);
file->addAction(m_load_psbt_action);
?
src/qt/bitcoingui.cpp
Outdated
//: The title for Restore Wallet File Windows | ||
tr("Load Wallet Backup"), QString(), | ||
//: The file extension for Restore Wallet File Windows | ||
tr("Wallet Data File (*.dat)"), nullptr); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This line and this one
Line 216 in c99f58a
tr("Wallet Data") + QLatin1String(" (*.dat)"), nullptr); |
And please separate untranslatable file extension from the translatable string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in e7a3f69.
The file extension is now separated from the file format name.
src/qt/bitcoingui.cpp
Outdated
tr("Wallet Data File (*.dat)"), nullptr); | ||
if (backup_file.isEmpty()) return; | ||
|
||
bool walletNameOk; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow our naming convention:
bool walletNameOk; | |
bool wallet_name_ok; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in e7a3f69.
src/qt/bitcoingui.cpp
Outdated
|
||
bool walletNameOk; | ||
//: Title of the Restore Wallet input dialog (where the wallet name is entered) | ||
QString walletName = QInputDialog::getText(this, tr("Restore Name"), tr("Wallet Name:"), QLineEdit::Normal, "", &walletNameOk); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please follow our naming convention:
QString walletName = QInputDialog::getText(this, tr("Restore Name"), tr("Wallet Name:"), QLineEdit::Normal, "", &walletNameOk); | |
QString wallet_name = QInputDialog::getText(this, tr("Restore Name"), tr("Wallet Name:"), QLineEdit::Normal, "", &walletNameOk); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in e7a3f69.
src/qt/walletcontroller.cpp
Outdated
if (m_wallet_model) Q_EMIT restored(m_wallet_model); | ||
|
||
Q_EMIT finished(); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a newline?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in e7a3f69.
Co-authored-by: Shashwat Vangani <[email protected]> Co-authored-by: furszy <[email protected]>
c99f58a
to
e7a3f69
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK, could use a release note
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes since my last review:
- renamed
walletName
→wallet_name
- renamed
walletNameOk
→wallet_name_ok
- The connection between restored and set current wallet has been changed to
Qt::QueuedConnection
, which is explained in this comment Add Wallet Restore in the GUI #471 (review)). On a side note, a very nice catch of bug indeed, @furszy! - The backup wallet and restore wallet options are grouped in a menu group.
- Declared class
path.h
at the beginning ofwalletcontroller.h
to facilitate usingfs::path
.
I successfully compiled this PR on Ubuntu 22.04
with Qt version 5.15.3
. I was able to test that the backup wallet and restore wallet are visually grouped in the GUI.
Screenshot:
I agree with @jarolrod. Adding release notes would be a good idea!
Added a release note in a new commit (bc13ec8) to not invalidate the ACKs for the previous one. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
utACK bc13ec8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK bc13ec8
//: Title of the Restore Wallet input dialog (where the wallet name is entered) | ||
QString wallet_name = QInputDialog::getText(this, tr("Restore Name"), tr("Wallet Name:"), QLineEdit::Normal, "", &wallet_name_ok); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A translator comment followed by a line with more than one tr()
could not work as expected.
9d9a098 gui: Fix translator comment for Restore Wallet QInputDialog (w0xlt) Pull request description: Fix translator comment for Restore Wallet `QInputDialog`, as suggested in #471 (comment). This also changes the window title name from `Restore Name` to `Restore Wallet` as it seems clearer. ACKs for top commit: shaavan: reACK 9d9a098 Tree-SHA512: 02aec661839215ab1183e4e92fa131671daa986339373a87c0a0e2c5e79a46f362a8846f4a5f6d630a99884a7949031982d13352336bd3f0573625826406dde8
… `QInputDialog` 9d9a098 gui: Fix translator comment for Restore Wallet QInputDialog (w0xlt) Pull request description: Fix translator comment for Restore Wallet `QInputDialog`, as suggested in bitcoin-core/gui#471 (comment). This also changes the window title name from `Restore Name` to `Restore Wallet` as it seems clearer. ACKs for top commit: shaavan: reACK 9d9a098 Tree-SHA512: 02aec661839215ab1183e4e92fa131671daa986339373a87c0a0e2c5e79a46f362a8846f4a5f6d630a99884a7949031982d13352336bd3f0573625826406dde8
This PR adds a menu item to restore a wallet from a backup file in the GUI.
Currently this option exists only in RPC interface.
Motivation: It makes easier for non-technical users to restore backups.