From 540fc749d9ec087b24ffd5b3f67d4764cd425eae Mon Sep 17 00:00:00 2001 From: Jonas Schnelli Date: Wed, 17 Aug 2016 14:09:47 +0200 Subject: [PATCH] [Qt] add HD enabled/disabled icon to the status bar https://github.com/bitcoin/bitcoin/pull/8517/commits/914154f0ccf2a18a273c7fdb3e80016732149303 --- contrib/debian/copyright | 139 +++++++++++++++++++++++++++++++ src/Makefile.qt.include | 2 + src/qt/bitcoin.qrc | 2 + src/qt/bitcoingui.cpp | 32 ++++--- src/qt/bitcoingui.h | 9 +- src/qt/res/icons/hd_disabled.png | Bin 0 -> 4328 bytes src/qt/res/icons/hd_enabled.png | Bin 0 -> 1889 bytes src/qt/res/src/hd_disabled.svg | 26 ++++++ src/qt/res/src/hd_enabled.svg | 13 +++ src/qt/walletmodel.cpp | 5 ++ src/qt/walletmodel.h | 2 + src/qt/walletview.cpp | 6 ++ src/qt/walletview.h | 2 + src/wallet/wallet.cpp | 83 +++++++++--------- src/wallet/wallet.h | 3 + 15 files changed, 274 insertions(+), 50 deletions(-) create mode 100644 contrib/debian/copyright create mode 100644 src/qt/res/icons/hd_disabled.png create mode 100644 src/qt/res/icons/hd_enabled.png create mode 100644 src/qt/res/src/hd_disabled.svg create mode 100644 src/qt/res/src/hd_enabled.svg diff --git a/contrib/debian/copyright b/contrib/debian/copyright new file mode 100644 index 000000000..cc4606ca8 --- /dev/null +++ b/contrib/debian/copyright @@ -0,0 +1,139 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: Bitcoin +Upstream-Contact: Satoshi Nakamoto + irc://#bitcoin@freenode.net +Source: https://github.com/bitcoin/bitcoin + +Files: * +Copyright: 2009-2016, Bitcoin Core Developers +License: Expat +Comment: The Bitcoin Core Developers encompasses the current developers listed on bitcoin.org, + as well as the numerous contributors to the project. + +Files: debian/* +Copyright: 2010-2011, Jonas Smedegaard + 2011, Matt Corallo +License: GPL-2+ + +Files: debian/manpages/* +Copyright: Micah Anderson +License: GPL-3+ + +Files: src/qt/res/icons/add.png + src/qt/res/icons/address-book.png + src/qt/res/icons/chevron.png + src/qt/res/icons/configure.png + src/qt/res/icons/debugwindow.png + src/qt/res/icons/edit.png + src/qt/res/icons/editcopy.png + src/qt/res/icons/editpaste.png + src/qt/res/icons/export.png + src/qt/res/icons/eye.png + src/qt/res/icons/filesave.png + src/qt/res/icons/history.png + src/qt/res/icons/info.png + src/qt/res/icons/key.png + src/qt/res/icons/lock_*.png + src/qt/res/icons/open.png + src/qt/res/icons/overview.png + src/qt/res/icons/quit.png + src/qt/res/icons/receive.png + src/qt/res/icons/remove.png + src/qt/res/icons/send.png + src/qt/res/icons/synced.png + src/qt/res/icons/transaction*.png + src/qt/res/icons/tx_output.png + src/qt/res/icons/warning.png +Copyright: Stephen Hutchings (and more) + http://typicons.com +License: Expat +Comment: Site: https://github.com/stephenhutchings/typicons.font + +Files: src/qt/res/icons/connect*.png + src/qt/res/src/connect-*.svg +Copyright: Marco Falke +License: Expat +Comment: Inspired by Stephan Hutchings Typicons + +Files: src/qt/res/icons/tx_mined.png + src/qt/res/src/mine.svg + src/qt/res/icons/fontbigger.png + src/qt/res/icons/fontsmaller.png + src/qt/res/icons/hd_disabled.png + src/qt/res/src/hd_disabled.svg + src/qt/res/icons/hd_enabled.png + src/qt/res/src/hd_enabled.svg +Copyright: Jonas Schnelli +License: Expat +Comment: + +Files: src/qt/res/icons/clock*.png + src/qt/res/icons/eye_*.png + src/qt/res/icons/verify.png + src/qt/res/icons/tx_in*.png + src/qt/res/src/clock_*.svg + src/qt/res/src/tx_*.svg + src/qt/res/src/verify.svg +Copyright: Stephan Hutching, Jonas Schnelli +License: Expat +Comment: Modifications of Stephan Hutchings Typicons + +Files: src/qt/res/icons/about.png + src/qt/res/icons/bitcoin.* + share/pixmaps/bitcoin* + src/qt/res/src/bitcoin.svg +Copyright: Bitboy, Jonas Schnelli +License: public-domain +Comment: Site: https://bitcointalk.org/?topic=1756.0 + + +License: Expat + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + . + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +License: GPL-2+ + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2, or (at your option) any + later version. + . + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. +Comment: + On Debian systems the GNU General Public License (GPL) version 2 is + located in '/usr/share/common-licenses/GPL-2'. + . + You should have received a copy of the GNU General Public License along + with this program. If not, see . + +License: GPL-3+ + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU General Public License, Version 3 or any + later version published by the Free Software Foundation. +Comment: + On Debian systems the GNU General Public License (GPL) version 3 is + located in '/usr/share/common-licenses/GPL-3'. + . + You should have received a copy of the GNU General Public License along + with this program. If not, see . + +License: public-domain + This work is in the public domain. diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 135ff070b..32692bff2 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -251,6 +251,8 @@ RES_ICONS = \ qt/res/icons/eye_minus.png \ qt/res/icons/eye_plus.png \ qt/res/icons/filesave.png \ + qt/res/icons/hd_disabled.png \ + qt/res/icons/hd_enabled.png \ qt/res/icons/history.png \ qt/res/icons/info.png \ qt/res/icons/key.png \ diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 7d4ab3e53..5905c6679 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -48,6 +48,8 @@ res/icons/warning.png res/icons/staking_on.png res/icons/staking_off.png + res/icons/hd_enabled.png + res/icons/hd_disabled.png res/movies/spinner-000.png diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index f7c1b80e0..c6dbd7ca7 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -79,7 +79,8 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n clientModel(0), walletFrame(0), unitDisplayControl(0), - labelEncryptionIcon(0), + labelWalletEncryptionIcon(0), + labelWalletHDStatusIcon(0), labelConnectionsIcon(0), labelBlocksIcon(0), progressBarLabel(0), @@ -195,7 +196,8 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n frameBlocksLayout->setContentsMargins(3,0,3,0); frameBlocksLayout->setSpacing(3); unitDisplayControl = new UnitDisplayStatusBarControl(platformStyle); - labelEncryptionIcon = new QLabel(); + labelWalletEncryptionIcon = new QLabel(); + labelWalletHDStatusIcon = new QLabel(); labelConnectionsIcon = new QLabel(); labelBlocksIcon = new QLabel(); labelStakingIcon = new QLabel(); @@ -205,7 +207,8 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *platformStyle, const NetworkStyle *n frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(unitDisplayControl); frameBlocksLayout->addStretch(); - frameBlocksLayout->addWidget(labelEncryptionIcon); + frameBlocksLayout->addWidget(labelWalletEncryptionIcon); + frameBlocksLayout->addWidget(labelWalletHDStatusIcon); } frameBlocksLayout->addStretch(); frameBlocksLayout->addWidget(labelStakingIcon); @@ -975,12 +978,21 @@ bool BitcoinGUI::handlePaymentRequest(const SendCoinsRecipient& recipient) return false; } +void BitcoinGUI::setHDStatus(int hdEnabled) +{ + labelWalletHDStatusIcon->setPixmap(platformStyle->SingleColorIcon(hdEnabled ? ":/icons/hd_enabled" : ":/icons/hd_disabled").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelWalletHDStatusIcon->setToolTip(hdEnabled ? tr("HD key generation is enabled") : tr("HD key generation is disabled")); + + // eventually disable the QLabel to set its opacity to 50% + labelWalletHDStatusIcon->setEnabled(hdEnabled); +} + void BitcoinGUI::setEncryptionStatus(int status) { switch(status) { case WalletModel::Unencrypted: - labelEncryptionIcon->hide(); + labelWalletEncryptionIcon->hide(); encryptWalletAction->setChecked(false); changePassphraseAction->setEnabled(false); encryptWalletAction->setEnabled(true); @@ -988,9 +1000,9 @@ void BitcoinGUI::setEncryptionStatus(int status) lockWalletAction->setVisible(false); break; case WalletModel::Unlocked: - labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); - labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked")); + labelWalletEncryptionIcon->show(); + labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_open").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelWalletEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently unlocked")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported @@ -998,9 +1010,9 @@ void BitcoinGUI::setEncryptionStatus(int status) lockWalletAction->setVisible(true); break; case WalletModel::Locked: - labelEncryptionIcon->show(); - labelEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); - labelEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked")); + labelWalletEncryptionIcon->show(); + labelWalletEncryptionIcon->setPixmap(platformStyle->SingleColorIcon(":/icons/lock_closed").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE)); + labelWalletEncryptionIcon->setToolTip(tr("Wallet is encrypted and currently locked")); encryptWalletAction->setChecked(true); changePassphraseAction->setEnabled(true); encryptWalletAction->setEnabled(false); // TODO: decrypt currently not supported diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 65e7638b1..3923ed127 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -81,7 +81,8 @@ private: WalletFrame *walletFrame; UnitDisplayStatusBarControl *unitDisplayControl; - QLabel *labelEncryptionIcon; + QLabel *labelWalletEncryptionIcon; + QLabel *labelWalletHDStatusIcon; QLabel *labelConnectionsIcon; QLabel *labelBlocksIcon; QLabel *progressBarLabel; @@ -173,6 +174,12 @@ public Q_SLOTS: */ void setEncryptionStatus(int status); + /** Set the hd-enabled status as shown in the UI. + @param[in] status current hd enabled status + @see WalletModel::EncryptionStatus + */ + void setHDStatus(int hdEnabled); + bool handlePaymentRequest(const SendCoinsRecipient& recipient); /** Show incoming transaction notification for new transactions. */ diff --git a/src/qt/res/icons/hd_disabled.png b/src/qt/res/icons/hd_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..687b6d2e38e9e3f8955072574ce644735a249982 GIT binary patch literal 4328 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 HpS|$k8tbb^ literal 0 HcmV?d00001 diff --git a/src/qt/res/icons/hd_enabled.png b/src/qt/res/icons/hd_enabled.png new file mode 100644 index 0000000000000000000000000000000000000000..568dde1cd1c1dba2dc1d575365ecd89aa7e55f68 GIT binary patch literal 1889 zcmb_dYfuwc6kZ@AP*Lea@Frmh+xa8 zbwEae`r;v0d=zN4ty6q}jt?jxR%DP@E!N3cD+mQgu~6&=0sEu$PrG+_&pmg}_nmX^ z`F3`XI40cD!Nmap0LRD(frPX{bo+V<4bbKUL9bv?fIAe@dY22!0tEeGs!5{;NB+wv)0yJpSv^d8QOr7H8kaNp2 zLc!g;B8u%^-rQWTmgSpwZ3JYVqk~A`c8QD0C1^XIQp06DSh>d#FY; z8;uhZvgB8w+wP-=3BQpySOuY?J2{BXyPVJeap1T(QoP5(*)!elR z=EOo|F_5LRf9v$j5-A_cbXK>dGpl?=OUfN1b$#9b#5no6bVLexQbW%`X~OP>u|VVP zbM%^){RXf`PIYRpl1GL1Q1b%XF9d-;nI4e4*Ne*MJgqr*zI*ld58Ackp--;b)TL4P z4B$Z%X(Ts}|V%ezc*YdeN&_ z>+5RelBeD~4%{y^4eXV|lJ1H=>1OZVqK%ZM6>&v(qdq_9W;N2{XFiWbJAVqiyy5@u z&}z@cU_)!X`^w`^q!srRaVSkte)CIADhT0b8H*CLX>sLOjQ3XEYTiIOMei-fy(T-) zKRn4h^d(Jlxaca}nH^epBCG%HLX)vrukdW!ru@p@6~9=#&*_O zot|`6M+9|X|8a>d4={-r4ACY7OA_*d z$ze%dzbrYdsMkn|fNBa_7O{8%u(cs{SNou>>Q07N@vrvP`;6JYeGPB;;M^0jve|E^nljXT~{qHBbl`Jm+Chr_j zne7TqCXid7?hJSA1zs+x=--&>#o0NKv}?Y7$C|i92W_n6_pQc?gjSo6s4nar6rWjg zTVJ2Op#zy{80{C+tsW;|csTNtUH{VBbuY?1a}sH|y#6h#iL3SVE?qwxy~29zny@k9 zO3H_ZZ8<<$-}q2E4TqXPTMU+V>22iYgNZyKM0RRGPg90F=|S%EL&xR5PnQ!lvGKcs z$BNPsv9nqB)YV#br29eaj&8yBhN0bies4NxPyHn>C91rx#a*Y2X3VcBbveH>XfWKI zj|H~f^yFs6ms_7}i8TxRq85Wky6in)6d$Kjn%tk8cAQ9er56BYNhkLw zo|&M<=h+oH4(M$b9!^rNKX&vzd?~3Uz0H6dcQ8`g<_uo$dax-$#2EW7_;j((HezXm zXjlWRNl8i=(^rDrjIZyd_vVgvQc$4x?xjC-Iu2m|!%?}nZ<^gGT!6g)j}hVVin0uN XRMO0!1b*IZ`RPT5#RzIclXm_E9we}T literal 0 HcmV?d00001 diff --git a/src/qt/res/src/hd_disabled.svg b/src/qt/res/src/hd_disabled.svg new file mode 100644 index 000000000..035f4431c --- /dev/null +++ b/src/qt/res/src/hd_disabled.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/qt/res/src/hd_enabled.svg b/src/qt/res/src/hd_enabled.svg new file mode 100644 index 000000000..cbaa16f8f --- /dev/null +++ b/src/qt/res/src/hd_enabled.svg @@ -0,0 +1,13 @@ + + + + + + + + + diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index 637858ba9..a1c26b3dc 100644 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -692,3 +692,8 @@ unsigned long long WalletModel::updateWeight() return wallet->GetStakeWeight(); } + +bool WalletModel::hdEnabled() const +{ + return wallet->IsHDEnabled(); +} diff --git a/src/qt/walletmodel.h b/src/qt/walletmodel.h index b6ae13234..75f102388 100644 --- a/src/qt/walletmodel.h +++ b/src/qt/walletmodel.h @@ -201,6 +201,8 @@ public: bool saveReceiveRequest(const std::string &sAddress, const int64_t nId, const std::string &sRequest); unsigned long long updateWeight(); + bool hdEnabled() const; + private: CWallet *wallet; bool fHaveWatchOnly; diff --git a/src/qt/walletview.cpp b/src/qt/walletview.cpp index b5e810cf4..a1b5b2131 100644 --- a/src/qt/walletview.cpp +++ b/src/qt/walletview.cpp @@ -98,6 +98,9 @@ void WalletView::setBitcoinGUI(BitcoinGUI *gui) // Pass through transaction notifications connect(this, SIGNAL(incomingTransaction(QString,int,CAmount,QString,QString,QString)), gui, SLOT(incomingTransaction(QString,int,CAmount,QString,QString,QString))); + + // Connect HD enabled state signal + connect(this, SIGNAL(hdEnabledStatusChanged(int)), gui, SLOT(setHDStatus(int))); } } @@ -130,6 +133,9 @@ void WalletView::setWalletModel(WalletModel *walletModel) connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SIGNAL(encryptionStatusChanged(int))); updateEncryptionStatus(); + // update HD status + Q_EMIT hdEnabledStatusChanged(walletModel->hdEnabled()); + // Balloon pop-up for new transaction connect(walletModel->getTransactionTableModel(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(processNewTransaction(QModelIndex,int,int))); diff --git a/src/qt/walletview.h b/src/qt/walletview.h index e45aea1ca..ae579a2e2 100644 --- a/src/qt/walletview.h +++ b/src/qt/walletview.h @@ -121,6 +121,8 @@ Q_SIGNALS: void message(const QString &title, const QString &message, unsigned int style); /** Encryption status of wallet changed */ void encryptionStatusChanged(int status); + /** HD-Enabled status of wallet changed (only possible during startup) */ + void hdEnabledStatusChanged(int hdEnabled); /** Notify that a new transaction appeared */ void incomingTransaction(const QString& date, int unit, const CAmount& amount, const QString& type, const QString& address, const QString& label); }; diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index dc2c4700e..80a6e5864 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -101,48 +101,48 @@ CPubKey CWallet::GenerateNewKey() CKey secret; // Create new metadata - int64_t nCreationTime = GetTime(); - CKeyMetadata metadata(nCreationTime); + int64_t nCreationTime = GetTime(); + CKeyMetadata metadata(nCreationTime); - // use HD key derivation if HD was enabled during wallet creation - if (!hdChain.masterKeyID.IsNull()) { - // for now we use a fixed keypath scheme of m/0'/0'/k - CKey key; //master key seed (256bit) - CExtKey masterKey; //hd master key - CExtKey accountKey; //key at m/0' - CExtKey externalChainChildKey; //key at m/0'/0' - CExtKey childKey; //key at m/0'/0'/' + // use HD key derivation if HD was enabled during wallet creation + if (IsHDEnabled()) { + // for now we use a fixed keypath scheme of m/0'/0'/k + CKey key; //master key seed (256bit) + CExtKey masterKey; //hd master key + CExtKey accountKey; //key at m/0' + CExtKey externalChainChildKey; //key at m/0'/0' + CExtKey childKey; //key at m/0'/0'/' - // try to get the master key - if (!GetKey(hdChain.masterKeyID, key)) - throw std::runtime_error("CWallet::GenerateNewKey(): Master key not found"); + // try to get the master key + if (!GetKey(hdChain.masterKeyID, key)) + throw std::runtime_error("CWallet::GenerateNewKey(): Master key not found"); - masterKey.SetMaster(key.begin(), key.size()); + masterKey.SetMaster(key.begin(), key.size()); - // derive m/0' - // use hardened derivation (child keys >= 0x80000000 are hardened after bip32) - masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT); + // derive m/0' + // use hardened derivation (child keys >= 0x80000000 are hardened after bip32) + masterKey.Derive(accountKey, BIP32_HARDENED_KEY_LIMIT); - // derive m/0'/0' - accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT); + // derive m/0'/0' + accountKey.Derive(externalChainChildKey, BIP32_HARDENED_KEY_LIMIT); - // derive child key at next index, skip keys already known to the wallet - do - { - // always derive hardened keys - // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range - // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649 - externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT); - metadata.hdKeypath = "m/0'/0'/"+std::to_string(hdChain.nExternalChainCounter)+"'"; - metadata.hdMasterKeyID = hdChain.masterKeyID; - // increment childkey index - hdChain.nExternalChainCounter++; - } while(HaveKey(childKey.key.GetPubKey().GetID())); - secret = childKey.key; + // derive child key at next index, skip keys already known to the wallet + do + { + // always derive hardened keys + // childIndex | BIP32_HARDENED_KEY_LIMIT = derive childIndex in hardened child-index-range + // example: 1 | BIP32_HARDENED_KEY_LIMIT == 0x80000001 == 2147483649 + externalChainChildKey.Derive(childKey, hdChain.nExternalChainCounter | BIP32_HARDENED_KEY_LIMIT); + metadata.hdKeypath = "m/0'/0'/"+std::to_string(hdChain.nExternalChainCounter)+"'"; + metadata.hdMasterKeyID = hdChain.masterKeyID; + // increment childkey index + hdChain.nExternalChainCounter++; + } while(HaveKey(childKey.key.GetPubKey().GetID())); + secret = childKey.key; - // update the chain model in the database - if (!CWalletDB(strWalletFile).WriteHDChain(hdChain)) - throw std::runtime_error("CWallet::GenerateNewKey(): Writing HD chain model failed"); + // update the chain model in the database + if (!CWalletDB(strWalletFile).WriteHDChain(hdChain)) + throw std::runtime_error("CWallet::GenerateNewKey(): Writing HD chain model failed"); } else { secret.MakeNewKey(fCompressed); } @@ -962,7 +962,7 @@ bool CWallet::EncryptWallet(const SecureString& strWalletPassphrase) Unlock(strWalletPassphrase); // if we are using HD, replace the HD master key (seed) with a new one - if (!hdChain.masterKeyID.IsNull()) { + if (IsHDEnabled()) { CKey key; CPubKey masterPubKey = GenerateNewHDMasterKey(); if (!SetHDMasterKey(masterPubKey)) @@ -1507,6 +1507,11 @@ CAmount CWallet::GetChange(const CTransaction& tx) const return nChange; } +bool CWallet::IsHDEnabled() +{ + return !hdChain.masterKeyID.IsNull(); +} + int64_t CWalletTx::GetTxTime() const { int64_t n = nTimeSmart; @@ -3608,7 +3613,7 @@ bool CWallet::InitLoadWallet() RandAddSeedPerfmon(); // Create new keyUser and set as default key - if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && walletInstance->hdChain.masterKeyID.IsNull()) { + if (GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET) && !walletInstance->IsHDEnabled()) { // generate a new master key CPubKey masterPubKey = walletInstance->GenerateNewHDMasterKey(); if (!walletInstance->SetHDMasterKey(masterPubKey)) @@ -3625,9 +3630,9 @@ bool CWallet::InitLoadWallet() } else if (mapArgs.count("-usehd")) { bool useHD = GetBoolArg("-usehd", DEFAULT_USE_HD_WALLET); - if (!walletInstance->hdChain.masterKeyID.IsNull() && !useHD) + if (walletInstance->IsHDEnabled() && !useHD) return InitError(strprintf(_("Error loading %s: You can't disable HD on a already existing HD wallet"), walletFile)); - if (walletInstance->hdChain.masterKeyID.IsNull() && useHD) + if (!walletInstance->IsHDEnabled() && useHD) return InitError(strprintf(_("Error loading %s: You can't enable HD on a already existing non-HD wallet"), walletFile)); } diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 0d5dd0566..5886e1903 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -833,6 +833,9 @@ public: bool SetHDChain(const CHDChain& chain, bool memonly); const CHDChain& GetHDChain() { return hdChain; } + /* Returns true if HD is enabled */ + bool IsHDEnabled(); + /* Generates a new HD master key (will not be activated) */ CPubKey GenerateNewHDMasterKey();