Merge branch 'master' of https://github.com/bitcoin/bitcoin
authorWladimir J. van der Laan <laanwj@gmail.com>
Fri, 15 Jul 2011 14:08:38 +0000 (16:08 +0200)
committerWladimir J. van der Laan <laanwj@gmail.com>
Fri, 15 Jul 2011 14:42:44 +0000 (16:42 +0200)
1  2 
bitcoin-qt.pro
src/bitcoinrpc.cpp
src/init.cpp
src/net.h
src/qt/addresstablemodel.cpp
src/util.cpp
src/util.h
src/wallet.cpp
src/wallet.h

diff --cc bitcoin-qt.pro
index 9708b82,0000000..9af4c67
mode 100644,000000..100644
--- /dev/null
@@@ -1,139 -1,0 +1,141 @@@
 +TEMPLATE = app
 +TARGET =
 +INCLUDEPATH += src src/json src/cryptopp src/qt
 +DEFINES += QT_GUI
 +# DEFINES += SSL
 +CONFIG += no_include_pwd
 +
 +# for boost 1.37, add -mt to the boost libraries
 +unix:LIBS += -lssl -lcrypto -lboost_system -lboost_filesystem -lboost_program_options -lboost_thread -ldb_cxx
 +macx:DEFINES += __WXMAC_OSX__ MSG_NOSIGNAL=0 BOOST_FILESYSTEM_VERSION=3
 +macx:LIBS += -lboost_thread-mt -lboost_system-mt -lboost_filesystem-mt -lboost_program_options-mt
 +windows:DEFINES += __WXMSW__
 +windows:LIBS += -lssl -lcrypto -lboost_system-mgw44-mt-1_43 -lboost_filesystem-mgw44-mt-1_43 -lboost_program_options-mgw44-mt-1_43 -lboost_thread-mgw44-mt-1_43 -ldb_cxx -lws2_32 -lgdi32
 +
 +# for extra security against potential buffer overflows
 +QMAKE_CXXFLAGS += -fstack-protector 
 +QMAKE_LFLAGS += -fstack-protector
 +
 +# disable quite some warnings because bitcoin core "sins" a lot
 +QMAKE_CXXFLAGS_WARN_ON = -fdiagnostics-show-option -Wall -Wno-invalid-offsetof -Wno-unused-variable -Wno-unused-parameter -Wno-sign-compare -Wno-char-subscripts  -Wno-unused-value -Wno-sequence-point -Wno-parentheses -Wno-unknown-pragmas -Wno-switch
 +
 +# Input
 +DEPENDPATH += src/qt src src/cryptopp src json/include
 +HEADERS += src/qt/bitcoingui.h \
 +    src/qt/transactiontablemodel.h \
 +    src/qt/addresstablemodel.h \
 +    src/qt/optionsdialog.h \
 +    src/qt/sendcoinsdialog.h \
 +    src/qt/addressbookpage.h \
 +    src/qt/aboutdialog.h \
 +    src/qt/editaddressdialog.h \
 +    src/qt/bitcoinaddressvalidator.h \
 +    src/base58.h \
 +    src/bignum.h \
 +    src/util.h \
 +    src/uint256.h \
 +    src/serialize.h \
 +    src/cryptopp/stdcpp.h \
 +    src/cryptopp/smartptr.h \
 +    src/cryptopp/simple.h \
 +    src/cryptopp/sha.h \
 +    src/cryptopp/secblock.h \
 +    src/cryptopp/pch.h \
 +    src/cryptopp/misc.h \
 +    src/cryptopp/iterhash.h \
 +    src/cryptopp/cryptlib.h \
 +    src/cryptopp/cpu.h \
 +    src/cryptopp/config.h \
 +    src/strlcpy.h \
 +    src/main.h \
 +    src/net.h \
 +    src/key.h \
 +    src/db.h \
 +    src/script.h \
 +    src/noui.h \
 +    src/init.h \
 +    src/headers.h \
 +    src/irc.h \
 +    src/json/json_spirit_writer_template.h \
 +    src/json/json_spirit_writer.h \
 +    src/json/json_spirit_value.h \
 +    src/json/json_spirit_utils.h \
 +    src/json/json_spirit_stream_reader.h \
 +    src/json/json_spirit_reader_template.h \
 +    src/json/json_spirit_reader.h \
 +    src/json/json_spirit_error_position.h \
 +    src/json/json_spirit.h \
 +    src/qt/clientmodel.h \
 +    src/qt/guiutil.h \
 +    src/qt/transactionrecord.h \
 +    src/qt/guiconstants.h \
 +    src/qt/optionsmodel.h \
 +    src/qt/monitoreddatamapper.h \
 +    src/qtui.h \
 +    src/qt/transactiondesc.h \
 +    src/qt/transactiondescdialog.h \
 +    src/qt/bitcoinamountfield.h \
 +    src/wallet.h \
 +    src/keystore.h \
 +    src/qt/transactionfilterproxy.h \
 +    src/qt/transactionview.h \
 +    src/qt/walletmodel.h \
 +    src/bitcoinrpc.h \
 +    src/qt/overviewpage.h \
 +    src/qt/csvmodelwriter.h \
-     src/qt/qtwin.h
++    src/qt/qtwin.h \
++    src/crypter.h
 +SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \
 +    src/qt/transactiontablemodel.cpp \
 +    src/qt/addresstablemodel.cpp \
 +    src/qt/optionsdialog.cpp \
 +    src/qt/sendcoinsdialog.cpp \
 +    src/qt/addressbookpage.cpp \
 +    src/qt/aboutdialog.cpp \
 +    src/qt/editaddressdialog.cpp \
 +    src/qt/bitcoinaddressvalidator.cpp \
 +    src/cryptopp/sha.cpp \
 +    src/cryptopp/cpu.cpp \
 +    src/util.cpp \
 +    src/script.cpp \
 +    src/main.cpp \
 +    src/init.cpp \
 +    src/net.cpp \
 +    src/irc.cpp \
 +    src/db.cpp \
 +    src/json/json_spirit_writer.cpp \
 +    src/json/json_spirit_value.cpp \
 +    src/json/json_spirit_reader.cpp \
 +    src/qt/clientmodel.cpp \
 +    src/qt/guiutil.cpp \
 +    src/qt/transactionrecord.cpp \
 +    src/qt/optionsmodel.cpp \
 +    src/qt/monitoreddatamapper.cpp \
 +    src/qt/transactiondesc.cpp \
 +    src/qt/transactiondescdialog.cpp \
 +    src/qt/bitcoinstrings.cpp \
 +    src/qt/bitcoinamountfield.cpp \
 +    src/wallet.cpp \
 +    src/keystore.cpp \
 +    src/qt/transactionfilterproxy.cpp \
 +    src/qt/transactionview.cpp \
 +    src/qt/walletmodel.cpp \
 +    src/bitcoinrpc.cpp \
 +    src/qt/overviewpage.cpp \
 +    src/qt/csvmodelwriter.cpp \
-     src/qt/qtwin.cpp
++    src/qt/qtwin.cpp \
++    src/crypter.cpp
 +
 +RESOURCES += \
 +    src/qt/bitcoin.qrc
 +
 +FORMS += \
 +    src/qt/forms/sendcoinsdialog.ui \
 +    src/qt/forms/addressbookpage.ui \
 +    src/qt/forms/aboutdialog.ui \
 +    src/qt/forms/editaddressdialog.ui \
 +    src/qt/forms/transactiondescdialog.ui \
 +    src/qt/forms/overviewpage.ui
 +
 +CODECFORTR = UTF-8
 +TRANSLATIONS = src/qt/locale/bitcoin_nl.ts src/qt/locale/bitcoin_de.ts
Simple merge
diff --cc src/init.cpp
Simple merge
diff --cc src/net.h
Simple merge
index 9ca7542,0000000..4578ca7
mode 100644,000000..100644
--- /dev/null
@@@ -1,328 -1,0 +1,329 @@@
 +#include "addresstablemodel.h"
 +#include "guiutil.h"
 +
 +#include "headers.h"
 +
 +#include <QFont>
 +#include <QColor>
 +
 +const QString AddressTableModel::Send = "S";
 +const QString AddressTableModel::Receive = "R";
 +
 +struct AddressTableEntry
 +{
 +    enum Type {
 +        Sending,
 +        Receiving
 +    };
 +
 +    Type type;
 +    QString label;
 +    QString address;
 +
 +    AddressTableEntry() {}
 +    AddressTableEntry(Type type, const QString &label, const QString &address):
 +        type(type), label(label), address(address) {}
 +};
 +
 +// Private implementation
 +struct AddressTablePriv
 +{
 +    CWallet *wallet;
 +    QList<AddressTableEntry> cachedAddressTable;
 +
 +    AddressTablePriv(CWallet *wallet):
 +            wallet(wallet) {}
 +
 +    void refreshAddressTable()
 +    {
 +        cachedAddressTable.clear();
 +
-         CRITICAL_BLOCK(wallet->cs_mapKeys)
++        CRITICAL_BLOCK(cs_mapPubKeys)
 +        CRITICAL_BLOCK(wallet->cs_mapAddressBook)
 +        {
 +            BOOST_FOREACH(const PAIRTYPE(std::string, std::string)& item, wallet->mapAddressBook)
 +            {
 +                std::string strAddress = item.first;
 +                std::string strName = item.second;
 +                uint160 hash160;
 +                bool fMine = (AddressToHash160(strAddress, hash160) && mapPubKeys.count(hash160));
 +                cachedAddressTable.append(AddressTableEntry(fMine ? AddressTableEntry::Receiving : AddressTableEntry::Sending,
 +                                  QString::fromStdString(strName),
 +                                  QString::fromStdString(strAddress)));
 +            }
 +        }
 +    }
 +
 +    int size()
 +    {
 +        return cachedAddressTable.size();
 +    }
 +
 +    AddressTableEntry *index(int idx)
 +    {
 +        if(idx >= 0 && idx < cachedAddressTable.size())
 +        {
 +            return &cachedAddressTable[idx];
 +        }
 +        else
 +        {
 +            return 0;
 +        }
 +    }
 +};
 +
 +AddressTableModel::AddressTableModel(CWallet *wallet, QObject *parent) :
 +    QAbstractTableModel(parent),wallet(wallet),priv(0)
 +{
 +    columns << tr("Label") << tr("Address");
 +    priv = new AddressTablePriv(wallet);
 +    priv->refreshAddressTable();
 +}
 +
 +AddressTableModel::~AddressTableModel()
 +{
 +    delete priv;
 +}
 +
 +int AddressTableModel::rowCount(const QModelIndex &parent) const
 +{
 +    Q_UNUSED(parent);
 +    return priv->size();
 +}
 +
 +int AddressTableModel::columnCount(const QModelIndex &parent) const
 +{
 +    Q_UNUSED(parent);
 +    return columns.length();
 +}
 +
 +QVariant AddressTableModel::data(const QModelIndex &index, int role) const
 +{
 +    if(!index.isValid())
 +        return QVariant();
 +
 +    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
 +
 +    if(role == Qt::DisplayRole || role == Qt::EditRole)
 +    {
 +        switch(index.column())
 +        {
 +        case Label:
 +            if(rec->label.isEmpty() && role == Qt::DisplayRole)
 +            {
 +                return tr("(no label)");
 +            }
 +            else
 +            {
 +                return rec->label;
 +            }
 +        case Address:
 +            return rec->address;
 +        }
 +    }
 +    else if (role == Qt::FontRole)
 +    {
 +        QFont font;
 +        if(index.column() == Address)
 +        {
 +            font = GUIUtil::bitcoinAddressFont();
 +        }
 +        return font;
 +    }
 +    else if (role == TypeRole)
 +    {
 +        switch(rec->type)
 +        {
 +        case AddressTableEntry::Sending:
 +            return Send;
 +        case AddressTableEntry::Receiving:
 +            return Receive;
 +        default: break;
 +        }
 +    }
 +    return QVariant();
 +}
 +
 +bool AddressTableModel::setData(const QModelIndex & index, const QVariant & value, int role)
 +{
 +    if(!index.isValid())
 +        return false;
 +    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
 +
 +    if(role == Qt::EditRole)
 +    {
 +        switch(index.column())
 +        {
 +        case Label:
 +            wallet->SetAddressBookName(rec->address.toStdString(), value.toString().toStdString());
 +            rec->label = value.toString();
 +            break;
 +        case Address:
 +            // Refuse to set invalid address
 +            if(!validateAddress(value.toString()))
 +                return false;
 +            // Double-check that we're not overwriting receiving address
 +            if(rec->type == AddressTableEntry::Sending)
 +            {
 +                CRITICAL_BLOCK(wallet->cs_mapAddressBook)
 +                {
 +                    // Remove old entry
 +                    wallet->DelAddressBookName(rec->address.toStdString());
 +                    // Add new entry with new address
 +                    wallet->SetAddressBookName(value.toString().toStdString(), rec->label.toStdString());
 +                }
 +
 +                rec->address = value.toString();
 +            }
 +            break;
 +        }
 +        emit dataChanged(index, index);
 +
 +        return true;
 +    }
 +    return false;
 +}
 +
 +QVariant AddressTableModel::headerData(int section, Qt::Orientation orientation, int role) const
 +{
 +    if(orientation == Qt::Horizontal)
 +    {
 +        if(role == Qt::DisplayRole)
 +        {
 +            return columns[section];
 +        }
 +    }
 +    return QVariant();
 +}
 +
 +Qt::ItemFlags AddressTableModel::flags(const QModelIndex & index) const
 +{
 +    if(!index.isValid())
 +        return 0;
 +    AddressTableEntry *rec = static_cast<AddressTableEntry*>(index.internalPointer());
 +
 +    Qt::ItemFlags retval = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
 +    // Can edit address and label for sending addresses,
 +    // and only label for receiving addresses.
 +    if(rec->type == AddressTableEntry::Sending ||
 +      (rec->type == AddressTableEntry::Receiving && index.column()==Label))
 +    {
 +        retval |= Qt::ItemIsEditable;
 +    }
 +    return retval;
 +}
 +
 +QModelIndex AddressTableModel::index(int row, int column, const QModelIndex & parent) const
 +{
 +    Q_UNUSED(parent);
 +    AddressTableEntry *data = priv->index(row);
 +    if(data)
 +    {
 +        return createIndex(row, column, priv->index(row));
 +    }
 +    else
 +    {
 +        return QModelIndex();
 +    }
 +}
 +
 +void AddressTableModel::updateList()
 +{
 +    // Update internal model from Bitcoin core
 +    beginResetModel();
 +    priv->refreshAddressTable();
 +    endResetModel();
 +}
 +
 +QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address)
 +{
 +    std::string strLabel = label.toStdString();
 +    std::string strAddress = address.toStdString();
 +
 +    if(type == Send)
 +    {
 +        // Check for duplicate
 +        CRITICAL_BLOCK(wallet->cs_mapAddressBook)
 +        {
 +            if(wallet->mapAddressBook.count(strAddress))
 +            {
 +                return QString();
 +            }
 +        }
 +    }
 +    else if(type == Receive)
 +    {
 +        // Generate a new address to associate with given label, optionally
 +        // set as default receiving address.
-         strAddress = PubKeyToAddress(wallet->GetKeyFromKeyPool());
++        strAddress = PubKeyToAddress(wallet->GetOrReuseKeyFromPool());
 +    }
 +    else
 +    {
 +        return QString();
 +    }
 +    // Add entry and update list
-     wallet->SetAddressBookName(strAddress, strLabel);
++    CRITICAL_BLOCK(wallet->cs_mapAddressBook)
++        wallet->SetAddressBookName(strAddress, strLabel);
 +    updateList();
 +    return QString::fromStdString(strAddress);
 +}
 +
 +bool AddressTableModel::removeRows(int row, int count, const QModelIndex & parent)
 +{
 +    Q_UNUSED(parent);
 +    AddressTableEntry *rec = priv->index(row);
 +    if(count != 1 || !rec || rec->type == AddressTableEntry::Receiving)
 +    {
 +        // Can only remove one row at a time, and cannot remove rows not in model.
 +        // Also refuse to remove receiving addresses.
 +        return false;
 +    }
 +    CRITICAL_BLOCK(wallet->cs_mapAddressBook)
 +    {
 +        wallet->DelAddressBookName(rec->address.toStdString());
 +    }
 +    updateList();
 +    return true;
 +}
 +
 +void AddressTableModel::update()
 +{
 +
 +}
 +
 +bool AddressTableModel::validateAddress(const QString &address)
 +{
 +    uint160 hash160 = 0;
 +
 +    return AddressToHash160(address.toStdString(), hash160);
 +}
 +
 +/* Look up label for address in address book, if not found return empty string.
 + */
 +QString AddressTableModel::labelForAddress(const QString &address) const
 +{
 +    CRITICAL_BLOCK(wallet->cs_mapAddressBook)
 +    {
 +        std::map<std::string, std::string>::iterator mi = wallet->mapAddressBook.find(address.toStdString());
 +        if (mi != wallet->mapAddressBook.end())
 +        {
 +            return QString::fromStdString(mi->second);
 +        }
 +    }
 +    return QString();
 +}
 +
 +int AddressTableModel::lookupAddress(const QString &address) const
 +{
 +    QModelIndexList lst = match(index(0, Address, QModelIndex()),
 +                                Qt::EditRole, address, 1, Qt::MatchExactly);
 +    if(lst.isEmpty())
 +    {
 +        return -1;
 +    }
 +    else
 +    {
 +        return lst.at(0).row();
 +    }
 +}
 +
diff --cc src/util.cpp
Simple merge
diff --cc src/util.h
Simple merge
diff --cc src/wallet.cpp
@@@ -98,9 -269,12 +269,12 @@@ bool CWallet::AddToWallet(const CWallet
          BOOST_FOREACH(const CTxOut& txout, wtx.vout)
          {
              if (txout.scriptPubKey == scriptDefaultKey)
-                 SetDefaultKey(GetKeyFromKeyPool());
+             {
+                 SetDefaultKey(GetOrReuseKeyFromPool());
+                 SetAddressBookName(PubKeyToAddress(vchDefaultKey), "");
+             }
          }
 -
 +#endif
          // Notify UI
          vWalletUpdated.push_back(hash);
  
diff --cc src/wallet.h
Simple merge