diff options
| author | chromatic <[email protected]> | 2021-04-21 16:35:06 -0700 |
|---|---|---|
| committer | chromatic <[email protected]> | 2021-05-23 19:37:09 -0700 |
| commit | 0565a85c7cd8df3ea3cfee2a5a9f252b870408ad (patch) | |
| tree | 4006f4d38b76df9d9f5c49e3563c730478889db5 /src/qt/importkeysdialog.cpp | |
| parent | Merge pull request #1976 from langerhans/1.14.4-travis-pgsql (diff) | |
| download | discoin-0565a85c7cd8df3ea3cfee2a5a9f252b870408ad.tar.xz discoin-0565a85c7cd8df3ea3cfee2a5a9f252b870408ad.zip | |
Add GUI to import private keys
Addresses GH #1808.
There are several possible future improvements:
* add a new icon for key import
* reduce duplication of code between the RPC private key importer and
the GUI private key importer
* improving error messages for various error states
Diffstat (limited to 'src/qt/importkeysdialog.cpp')
| -rw-r--r-- | src/qt/importkeysdialog.cpp | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/src/qt/importkeysdialog.cpp b/src/qt/importkeysdialog.cpp new file mode 100644 index 000000000..743a61d8b --- /dev/null +++ b/src/qt/importkeysdialog.cpp @@ -0,0 +1,164 @@ +// Copyright (c) 2021 The Dogecoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + +#include "importkeysdialog.h" +#include "ui_importkeysdialog.h" + +#include "base58.h" +#include "guiutil.h" +#include "platformstyle.h" +#include "validation.h" +#include "wallet/wallet.h" +#include "walletmodel.h" +#include "util.h" + +#include <QThread> +#include <QDebug> + +/* Object for executing key import commands in a separate thread. +*/ +class ImportKeyExecutor : public QObject +{ + Q_OBJECT + +public Q_SLOTS: + void rescan(CWallet*, CBlockIndex*); + +Q_SIGNALS: + void rescanWallet(CWallet*, CBlockIndex*); +}; + +#include "importkeysdialog.moc" + +void ImportKeyExecutor::rescan(CWallet* pwallet, CBlockIndex* genesisBlock) +{ + qWarning() << "started import key thread"; + pwallet->UpdateTimeFirstKey(1); + pwallet->ScanForWalletTransactions(genesisBlock, true); + qWarning() << "quitting import key thread"; + QObject::thread()->quit(); +} + +ImportKeysDialog::ImportKeysDialog(const PlatformStyle *_platformStyle, QWidget *parent) : + QDialog(parent), + ui(new Ui::ImportKeysDialog), + platformStyle(_platformStyle) +{ + ui->setupUi(this); + + /* Main elements init */ + if (fPruneMode) { + ui->rescanCheckBox->setEnabled(false); + } +} + +ImportKeysDialog::~ImportKeysDialog() +{ + thread.wait(); + delete ui; +} + +void ImportKeysDialog::on_okButton_clicked() +{ + if (importKey()) { + resetDialogValues(); + accept(); + }; +} + +void ImportKeysDialog::on_cancelButton_clicked() +{ + reject(); +} + +void ImportKeysDialog::on_resetButton_clicked() +{ + resetDialogValues(); +} + +bool ImportKeysDialog::importKey() +{ + const QString privateKey = ui->privateKey->text(); + const QString privateKeyLabel = ui->privateKeyLabel->text(); + const bool rescan = ui->rescanCheckBox->isChecked(); + + resetDialogValues(); + + CBitcoinSecret vchSecret; + bool fGood = vchSecret.SetString(privateKey.toStdString()); + if (!fGood) { + vchSecret.SetString(""); + ui->privateKeyImportTextMessage->setText(tr("Invalid private key; please check and try again!")); + return false; + } + + CKey key = vchSecret.GetKey(); + if (!key.IsValid()) { + vchSecret.SetString(""); + ui->privateKeyImportTextMessage->setText(tr("Invalid private key; please check and try again!")); + return false; + } + + CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); + CKeyID vchAddress = pubkey.GetID(); + + pwalletMain->MarkDirty(); + pwalletMain->SetAddressBook(vchAddress, privateKeyLabel.toStdString(), "receive"); + + if (pwalletMain->HaveKey(vchAddress)) { + vchSecret.SetString(""); + ui->privateKeyImportTextMessage->setText( + tr("Invalid address generated from private key; please check and try again!" + )); + return false; + } + + pwalletMain->mapKeyMetadata[vchAddress].nCreateTime = 1; + + if (!pwalletMain->AddKeyPubKey(key, pubkey)) { + vchSecret.SetString(""); + ui->privateKeyImportTextMessage->setText(tr("Failed to add private key.")); + return false; + } + + pwalletMain->UpdateTimeFirstKey(1); + + if (rescan) { + ImportKeyExecutor *executor = new ImportKeyExecutor(); + executor->moveToThread(&thread); + connect(this, SIGNAL(rescanWallet(CWallet*, CBlockIndex*)), executor, SLOT(rescan(CWallet*, CBlockIndex*))); + + // On stopExecutor signal + // - quit the Qt event loop in the execution thread + connect(this, SIGNAL(stopExecutor()), &thread, SLOT(quit())); + // - queue executor for deletion (in execution thread) + connect(&thread, SIGNAL(finished()), executor, SLOT(deleteLater()), Qt::DirectConnection); + + // Default implementation of QThread::run() simply spins up an event loop in the thread, + // which is what we want. + thread.start(); + ui->privateKeyImportTextMessage->setText(tr("Rescanning...")); + Q_EMIT rescanWallet(pwalletMain, chainActive.Genesis()); + } + + vchSecret.SetString(""); + return true; +} + +void ImportKeysDialog::resetDialogValues() +{ + ui->privateKey->clear(); + ui->privateKeyLabel->clear(); + ui->rescanCheckBox->setCheckState(Qt::Unchecked); +} + +void ImportKeysDialog::setOkButtonState(bool fState) +{ + ui->okButton->setEnabled(fState); +} |