Merge branch '0.5.x' into 0.6.0.x
authorLuke Dashjr <luke-jr+git@utopios.org>
Thu, 5 Apr 2012 22:22:47 +0000 (18:22 -0400)
committerLuke Dashjr <luke-jr+git@utopios.org>
Thu, 5 Apr 2012 22:22:47 +0000 (18:22 -0400)
Conflicts:
src/keystore.cpp

1  2 
src/crypter.cpp
src/keystore.cpp
src/qt/bitcoingui.cpp

diff --combined src/crypter.cpp
@@@ -1,4 -1,4 +1,4 @@@
 -// Copyright (c) 2011 The Bitcoin Developers
 +// Copyright (c) 2009-2012 The Bitcoin Developers
  // Distributed under the MIT/X11 software license, see the accompanying
  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  
@@@ -73,14 -73,16 +73,16 @@@ bool CCrypter::Encrypt(const CKeyingMat
  
      EVP_CIPHER_CTX ctx;
  
-     EVP_CIPHER_CTX_init(&ctx);
-     EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
-     EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
-     EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
+     bool fOk = true;
  
+     EVP_CIPHER_CTX_init(&ctx);
+     if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
+     if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
+     if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
      EVP_CIPHER_CTX_cleanup(&ctx);
  
+     if (!fOk) return false;
      vchCiphertext.resize(nCLen + nFLen);
      return true;
  }
@@@ -98,14 -100,16 +100,16 @@@ bool CCrypter::Decrypt(const std::vecto
  
      EVP_CIPHER_CTX ctx;
  
-     EVP_CIPHER_CTX_init(&ctx);
-     EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
-     EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
-     EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
+     bool fOk = true;
  
+     EVP_CIPHER_CTX_init(&ctx);
+     if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
+     if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
+     if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
      EVP_CIPHER_CTX_cleanup(&ctx);
  
+     if (!fOk) return false;
      vchPlaintext.resize(nPLen + nFLen);
      return true;
  }
diff --combined src/keystore.cpp
@@@ -1,12 -1,21 +1,12 @@@
  // Copyright (c) 2009-2010 Satoshi Nakamoto
 -// Copyright (c) 2011 The Bitcoin developers
 +// Copyright (c) 2009-2012 The Bitcoin developers
  // Distributed under the MIT/X11 software license, see the accompanying
  // file license.txt or http://www.opensource.org/licenses/mit-license.php.
  
  #include "headers.h"
 -#include "db.h"
  #include "crypter.h"
 -
 -std::vector<unsigned char> CKeyStore::GenerateNewKey()
 -{
 -    RandAddSeedPerfmon();
 -    CKey key;
 -    key.MakeNewKey();
 -    if (!AddKey(key))
 -        throw std::runtime_error("CKeyStore::GenerateNewKey() : AddKey failed");
 -    return key.GetPubKey();
 -}
 +#include "db.h"
 +#include "script.h"
  
  bool CKeyStore::GetPubKey(const CBitcoinAddress &address, std::vector<unsigned char> &vchPubKeyOut) const
  {
  
  bool CBasicKeyStore::AddKey(const CKey& key)
  {
 +    bool fCompressed = false;
 +    CSecret secret = key.GetSecret(fCompressed);
 +    CRITICAL_BLOCK(cs_KeyStore)
 +        mapKeys[CBitcoinAddress(key.GetPubKey())] = make_pair(secret, fCompressed);
 +    return true;
 +}
 +
 +bool CBasicKeyStore::AddCScript(const CScript& redeemScript)
 +{
      CRITICAL_BLOCK(cs_KeyStore)
 -        mapKeys[key.GetAddress()] = key.GetSecret();
 +        mapScripts[Hash160(redeemScript)] = redeemScript;
      return true;
  }
  
 +bool CBasicKeyStore::HaveCScript(const uint160& hash) const
 +{
 +    bool result;
 +    CRITICAL_BLOCK(cs_KeyStore)
 +        result = (mapScripts.count(hash) > 0);
 +    return result;
 +}
 +
 +
 +bool CBasicKeyStore::GetCScript(const uint160 &hash, CScript& redeemScriptOut) const
 +{
 +    CRITICAL_BLOCK(cs_KeyStore)
 +    {
 +        ScriptMap::const_iterator mi = mapScripts.find(hash);
 +        if (mi != mapScripts.end())
 +        {
 +            redeemScriptOut = (*mi).second;
 +            return true;
 +        }
 +    }
 +    return false;
 +}
 +
  bool CCryptoKeyStore::SetCrypted()
  {
      CRITICAL_BLOCK(cs_KeyStore)
      return true;
  }
  
 -std::vector<unsigned char> CCryptoKeyStore::GenerateNewKey()
 -{
 -    RandAddSeedPerfmon();
 -    CKey key;
 -    key.MakeNewKey();
 -    if (!AddKey(key))
 -        throw std::runtime_error("CCryptoKeyStore::GenerateNewKey() : AddKey failed");
 -    return key.GetPubKey();
 -}
 -
  bool CCryptoKeyStore::Unlock(const CKeyingMaterial& vMasterKeyIn)
  {
      CRITICAL_BLOCK(cs_KeyStore)
              CSecret vchSecret;
              if(!DecryptSecret(vMasterKeyIn, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
                  return false;
+             if (vchSecret.size() != 32)
+                 return false;
              CKey key;
 +            key.SetPubKey(vchPubKey);
              key.SetSecret(vchSecret);
              if (key.GetPubKey() == vchPubKey)
                  break;
@@@ -108,8 -96,7 +110,8 @@@ bool CCryptoKeyStore::AddKey(const CKey
  
          std::vector<unsigned char> vchCryptedSecret;
          std::vector<unsigned char> vchPubKey = key.GetPubKey();
 -        if (!EncryptSecret(vMasterKey, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
 +        bool fCompressed;
 +        if (!EncryptSecret(vMasterKey, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
              return false;
  
          if (!AddCryptedKey(key.GetPubKey(), vchCryptedSecret))
@@@ -146,7 -133,8 +148,9 @@@ bool CCryptoKeyStore::GetKey(const CBit
              CSecret vchSecret;
              if (!DecryptSecret(vMasterKey, vchCryptedSecret, Hash(vchPubKey.begin(), vchPubKey.end()), vchSecret))
                  return false;
+             if (vchSecret.size() != 32)
+                 return false;
 +            keyOut.SetPubKey(vchPubKey);
              keyOut.SetSecret(vchSecret);
              return true;
          }
@@@ -179,15 -167,14 +183,15 @@@ bool CCryptoKeyStore::EncryptKeys(CKeyi
              return false;
  
          fUseCrypto = true;
 -        CKey key;
          BOOST_FOREACH(KeyMap::value_type& mKey, mapKeys)
          {
 -            if (!key.SetSecret(mKey.second))
 +            CKey key;
 +            if (!key.SetSecret(mKey.second.first, mKey.second.second))
                  return false;
              const std::vector<unsigned char> vchPubKey = key.GetPubKey();
              std::vector<unsigned char> vchCryptedSecret;
 -            if (!EncryptSecret(vMasterKeyIn, key.GetSecret(), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
 +            bool fCompressed;
 +            if (!EncryptSecret(vMasterKeyIn, key.GetSecret(fCompressed), Hash(vchPubKey.begin(), vchPubKey.end()), vchCryptedSecret))
                  return false;
              if (!AddCryptedKey(vchPubKey, vchCryptedSecret))
                  return false;
diff --combined src/qt/bitcoingui.cpp
@@@ -1,14 -1,13 +1,14 @@@
  /*
   * Qt4 bitcoin GUI.
   *
 - * W.J. van der Laan 2011
 - * The Bitcoin Developers 2011
 + * W.J. van der Laan 20011-2012
 + * The Bitcoin Developers 20011-2012
   */
  #include "bitcoingui.h"
  #include "transactiontablemodel.h"
  #include "addressbookpage.h"
  #include "sendcoinsdialog.h"
 +#include "messagepage.h"
  #include "optionsdialog.h"
  #include "aboutdialog.h"
  #include "clientmodel.h"
@@@ -46,8 -45,6 +46,8 @@@
  #include <QStackedWidget>
  #include <QDateTime>
  #include <QMovie>
 +#include <QFileDialog>
 +#include <QDesktopServices>
  #include <QTimer>
  
  #include <QDragEnterEvent>
@@@ -103,17 -100,12 +103,17 @@@ BitcoinGUI::BitcoinGUI(QWidget *parent)
  
      sendCoinsPage = new SendCoinsDialog(this);
  
 +    messagePage = new MessagePage(this);
 +
      centralWidget = new QStackedWidget(this);
      centralWidget->addWidget(overviewPage);
      centralWidget->addWidget(transactionsPage);
      centralWidget->addWidget(addressBookPage);
      centralWidget->addWidget(receiveCoinsPage);
      centralWidget->addWidget(sendCoinsPage);
 +#ifdef FIRST_CLASS_MESSAGING
 +    centralWidget->addWidget(messagePage);
 +#endif
      setCentralWidget(centralWidget);
  
      // Create status bar
  
      // Status bar notification icons
      QFrame *frameBlocks = new QFrame();
 -    //frameBlocks->setFrameStyle(QFrame::Panel | QFrame::Sunken);
      frameBlocks->setContentsMargins(0,0,0,0);
      frameBlocks->setMinimumWidth(56);
      frameBlocks->setMaximumWidth(56);
  
  BitcoinGUI::~BitcoinGUI()
  {
 +    if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu)
 +        trayIcon->hide();
  #ifdef Q_WS_MAC
      delete appMenuBar;
  #endif
@@@ -203,25 -194,16 +203,25 @@@ void BitcoinGUI::createActions(
      sendCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_2));
      tabGroup->addAction(sendCoinsAction);
  
 -    connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormal()));
 +    messageAction = new QAction(QIcon(":/icons/edit"), tr("Sign &message"), this);
 +    messageAction->setToolTip(tr("Prove you control an address"));
 +#ifdef FIRST_CLASS_MESSAGING
 +    messageAction->setCheckable(true);
 +#endif
 +    tabGroup->addAction(messageAction);
 +
 +    connect(overviewAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
      connect(overviewAction, SIGNAL(triggered()), this, SLOT(gotoOverviewPage()));
 -    connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormal()));
 +    connect(historyAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
      connect(historyAction, SIGNAL(triggered()), this, SLOT(gotoHistoryPage()));
 -    connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormal()));
 +    connect(addressBookAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
      connect(addressBookAction, SIGNAL(triggered()), this, SLOT(gotoAddressBookPage()));
 -    connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormal()));
 +    connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
      connect(receiveCoinsAction, SIGNAL(triggered()), this, SLOT(gotoReceiveCoinsPage()));
 -    connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormal()));
 +    connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
      connect(sendCoinsAction, SIGNAL(triggered()), this, SLOT(gotoSendCoinsPage()));
 +    connect(messageAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
 +    connect(messageAction, SIGNAL(triggered()), this, SLOT(gotoMessagePage()));
  
      quitAction = new QAction(QIcon(":/icons/quit"), tr("E&xit"), this);
      quitAction->setToolTip(tr("Quit application"));
      openBitcoinAction = new QAction(QIcon(":/icons/bitcoin"), tr("Open &Bitcoin"), this);
      openBitcoinAction->setToolTip(tr("Show the Bitcoin window"));
      exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this);
 -    exportAction->setToolTip(tr("Export the current view to a file"));
 +    exportAction->setToolTip(tr("Export the data in the current tab to a file"));
      encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet"), this);
      encryptWalletAction->setToolTip(tr("Encrypt or decrypt wallet"));
      encryptWalletAction->setCheckable(true);
 +    backupWalletAction = new QAction(QIcon(":/icons/filesave"), tr("&Backup Wallet"), this);
 +    backupWalletAction->setToolTip(tr("Backup wallet to another location"));
      changePassphraseAction = new QAction(QIcon(":/icons/key"), tr("&Change Passphrase"), this);
      changePassphraseAction->setToolTip(tr("Change the passphrase used for wallet encryption"));
  
      connect(optionsAction, SIGNAL(triggered()), this, SLOT(optionsClicked()));
      connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutClicked()));
      connect(aboutQtAction, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
 -    connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormal()));
 +    connect(openBitcoinAction, SIGNAL(triggered()), this, SLOT(showNormalIfMinimized()));
      connect(encryptWalletAction, SIGNAL(triggered(bool)), this, SLOT(encryptWallet(bool)));
 +    connect(backupWalletAction, SIGNAL(triggered()), this, SLOT(backupWallet()));
      connect(changePassphraseAction, SIGNAL(triggered()), this, SLOT(changePassphrase()));
  }
  
@@@ -270,12 -249,6 +270,12 @@@ void BitcoinGUI::createMenuBar(
  
      // Configure the menus
      QMenu *file = appMenuBar->addMenu(tr("&File"));
 +    file->addAction(backupWalletAction);
 +    file->addAction(exportAction);
 +#ifndef FIRST_CLASS_MESSAGING
 +    file->addAction(messageAction);
 +#endif
 +    file->addSeparator();
      file->addAction(quitAction);
  
      QMenu *settings = appMenuBar->addMenu(tr("&Settings"));
@@@ -298,9 -271,6 +298,9 @@@ void BitcoinGUI::createToolBars(
      toolbar->addAction(receiveCoinsAction);
      toolbar->addAction(historyAction);
      toolbar->addAction(addressBookAction);
 +#ifdef FIRST_CLASS_MESSAGING
 +    toolbar->addAction(messageAction);
 +#endif
  
      QToolBar *toolbar2 = addToolBar(tr("Actions toolbar"));
      toolbar2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
@@@ -355,7 -325,6 +355,7 @@@ void BitcoinGUI::setWalletModel(WalletM
          addressBookPage->setModel(walletModel->getAddressTableModel());
          receiveCoinsPage->setModel(walletModel->getAddressTableModel());
          sendCoinsPage->setModel(walletModel);
 +        messagePage->setModel(walletModel);
  
          setEncryptionStatus(walletModel->getEncryptionStatus());
          connect(walletModel, SIGNAL(encryptionStatusChanged(int)), this, SLOT(setEncryptionStatus(int)));
@@@ -391,10 -360,6 +391,10 @@@ void BitcoinGUI::createTrayIcon(
      // Configuration of the tray icon (or dock icon) icon menu
      trayIconMenu->addAction(openBitcoinAction);
      trayIconMenu->addSeparator();
 +    trayIconMenu->addAction(messageAction);
 +#ifndef FIRST_CLASS_MESSAGING
 +    trayIconMenu->addSeparator();
 +#endif
      trayIconMenu->addAction(receiveCoinsAction);
      trayIconMenu->addAction(sendCoinsAction);
      trayIconMenu->addSeparator();
@@@ -515,7 -480,7 +515,7 @@@ void BitcoinGUI::setNumBlocks(int count
      }
  
      // Set icon state: spinning if catching up, tick otherwise
-     if(secs < 30*60)
+     if(secs < 90*60)
      {
          tooltip = tr("Up to date") + QString(".\n") + tooltip;
          labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE,STATUSBAR_ICONSIZE));
@@@ -692,26 -657,6 +692,26 @@@ void BitcoinGUI::gotoSendCoinsPage(
      disconnect(exportAction, SIGNAL(triggered()), 0, 0);
  }
  
 +void BitcoinGUI::gotoMessagePage()
 +{
 +#ifdef FIRST_CLASS_MESSAGING
 +    messageAction->setChecked(true);
 +    centralWidget->setCurrentWidget(messagePage);
 +
 +    exportAction->setEnabled(false);
 +    disconnect(exportAction, SIGNAL(triggered()), 0, 0);
 +#else
 +    messagePage->show();
 +    messagePage->setFocus();
 +#endif
 +}
 +
 +void BitcoinGUI::gotoMessagePage(QString addr)
 +{
 +    gotoMessagePage();
 +    messagePage->setAddress(addr);
 +}
 +
  void BitcoinGUI::dragEnterEvent(QDragEnterEvent *event)
  {
      // Accept only URLs
@@@ -727,24 -672,13 +727,24 @@@ void BitcoinGUI::dropEvent(QDropEvent *
          QList<QUrl> urls = event->mimeData()->urls();
          foreach(const QUrl &url, urls)
          {
 -            sendCoinsPage->handleURL(&url);
 +            sendCoinsPage->handleURL(url.toString());
          }
      }
  
      event->acceptProposedAction();
  }
  
 +void BitcoinGUI::handleURL(QString strURL)
 +{
 +    gotoSendCoinsPage();
 +    sendCoinsPage->handleURL(strURL);
 +
 +    if(!isActiveWindow())
 +        activateWindow();
 +
 +    showNormalIfMinimized();
 +}
 +
  void BitcoinGUI::setEncryptionStatus(int status)
  {
      switch(status)
@@@ -786,17 -720,6 +786,17 @@@ void BitcoinGUI::encryptWallet(bool sta
      setEncryptionStatus(walletModel->getEncryptionStatus());
  }
  
 +void BitcoinGUI::backupWallet()
 +{
 +    QString saveDir = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation);
 +    QString filename = QFileDialog::getSaveFileName(this, tr("Backup Wallet"), saveDir, tr("Wallet Data (*.dat)"));
 +    if(!filename.isEmpty()) {
 +        if(!walletModel->backupWallet(filename)) {
 +            QMessageBox::warning(this, tr("Backup Failed"), tr("There was an error trying to save the wallet data to the new location."));
 +        }
 +    }
 +}
 +
  void BitcoinGUI::changePassphrase()
  {
      AskPassphraseDialog dlg(AskPassphraseDialog::ChangePass, this);
@@@ -816,11 -739,3 +816,11 @@@ void BitcoinGUI::unlockWallet(
          dlg.exec();
      }
  }
 +
 +void BitcoinGUI::showNormalIfMinimized()
 +{
 +    if(!isVisible()) // Show, if hidden
 +        show();
 +    if(isMinimized()) // Unminimize, if minimized
 +        showNormal();
 +}