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 000000000..687b6d2e3 Binary files /dev/null and b/src/qt/res/icons/hd_disabled.png differ diff --git a/src/qt/res/icons/hd_enabled.png b/src/qt/res/icons/hd_enabled.png new file mode 100644 index 000000000..568dde1cd Binary files /dev/null and b/src/qt/res/icons/hd_enabled.png differ 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();