diff options
-rw-r--r-- | README | 21 | ||||
-rw-r--r-- | bitcoinrpc/.gitignore | 2 | ||||
-rw-r--r-- | bitcoinrpc/__init__.py | 0 | ||||
-rw-r--r-- | bitcoinrpc/authproxy.py | 140 | ||||
-rw-r--r-- | doc/build-unix.md | 14 | ||||
-rw-r--r-- | jsonrpc/__init__.py | 2 | ||||
-rw-r--r-- | jsonrpc/authproxy.py | 3 | ||||
-rw-r--r-- | jsonrpc/json.py | 9 | ||||
-rw-r--r-- | jsonrpc/proxy.py | 1 | ||||
-rw-r--r-- | setup.py | 15 | ||||
-rw-r--r-- | src/m4/bitcoin_qt.m4 | 12 | ||||
-rw-r--r-- | src/main.cpp | 18 | ||||
-rw-r--r-- | src/main.h | 1 | ||||
-rw-r--r-- | src/qt/addresstablemodel.cpp | 2 | ||||
-rw-r--r-- | src/qt/bitcoingui.cpp | 20 | ||||
-rw-r--r-- | src/qt/coincontroldialog.cpp | 16 | ||||
-rw-r--r-- | src/qt/forms/receivecoinsdialog.ui | 6 | ||||
-rw-r--r-- | src/qt/locale/bitcoin_en.ts | 13 | ||||
-rw-r--r-- | src/qt/optionsmodel.cpp | 23 | ||||
-rw-r--r-- | src/qt/optionsmodel.h | 3 | ||||
-rw-r--r-- | src/qt/receivecoinsdialog.cpp | 15 | ||||
-rw-r--r-- | src/qt/receivecoinsdialog.h | 2 | ||||
-rw-r--r-- | src/rpcmisc.cpp | 6 | ||||
-rw-r--r-- | src/test/checkblock_tests.cpp | 3 | ||||
-rw-r--r-- | src/test/data/script_invalid.json | 4 | ||||
-rw-r--r-- | src/test/data/script_valid.json | 4 | ||||
-rw-r--r-- | src/wallet.cpp | 7 |
27 files changed, 118 insertions, 244 deletions
diff --git a/README b/README deleted file mode 100644 index 9edd5a2121..0000000000 --- a/README +++ /dev/null @@ -1,21 +0,0 @@ -AuthServiceProxy is an improved version of python-jsonrpc. - -It includes the following generic improvements: - -- HTTP connections persist for the life of the AuthServiceProxy object -- sends protocol 'version', per JSON-RPC 1.1 -- sends proper, incrementing 'id' -- uses standard Python json lib - -It also includes the following bitcoin-specific details: - -- sends Basic HTTP authentication headers -- parses all JSON numbers that look like floats as Decimal - -Installation: - -- change the first line of setup.py to point to the directory of your installation of python 2.* -- run setup.py - -Note: This will only install bitcoinrpc. If you also want to install jsonrpc to preserve -backwards compatibility, you have to replace 'bitcoinrpc' with 'jsonrpc' in setup.py and run it again. diff --git a/bitcoinrpc/.gitignore b/bitcoinrpc/.gitignore deleted file mode 100644 index 2f78cf5b66..0000000000 --- a/bitcoinrpc/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -*.pyc - diff --git a/bitcoinrpc/__init__.py b/bitcoinrpc/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 --- a/bitcoinrpc/__init__.py +++ /dev/null diff --git a/bitcoinrpc/authproxy.py b/bitcoinrpc/authproxy.py deleted file mode 100644 index 2914477170..0000000000 --- a/bitcoinrpc/authproxy.py +++ /dev/null @@ -1,140 +0,0 @@ - -""" - Copyright 2011 Jeff Garzik - - AuthServiceProxy has the following improvements over python-jsonrpc's - ServiceProxy class: - - - HTTP connections persist for the life of the AuthServiceProxy object - (if server supports HTTP/1.1) - - sends protocol 'version', per JSON-RPC 1.1 - - sends proper, incrementing 'id' - - sends Basic HTTP authentication headers - - parses all JSON numbers that look like floats as Decimal - - uses standard Python json lib - - Previous copyright, from python-jsonrpc/jsonrpc/proxy.py: - - Copyright (c) 2007 Jan-Klaas Kollhof - - This file is part of jsonrpc. - - jsonrpc is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - This software 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 Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with this software; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -""" - -try: - import http.client as httplib -except ImportError: - import httplib -import base64 -import json -import decimal -try: - import urllib.parse as urlparse -except ImportError: - import urlparse - -USER_AGENT = "AuthServiceProxy/0.1" - -HTTP_TIMEOUT = 30 - - -class JSONRPCException(Exception): - def __init__(self, rpc_error): - Exception.__init__(self) - self.error = rpc_error - - -class AuthServiceProxy(object): - def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connection=None): - self.__service_url = service_url - self.__service_name = service_name - self.__url = urlparse.urlparse(service_url) - if self.__url.port is None: - port = 80 - else: - port = self.__url.port - self.__id_count = 0 - (user, passwd) = (self.__url.username, self.__url.password) - try: - user = user.encode('utf8') - except AttributeError: - pass - try: - passwd = passwd.encode('utf8') - except AttributeError: - pass - authpair = user + b':' + passwd - self.__auth_header = b'Basic ' + base64.b64encode(authpair) - - if connection: - # Callables re-use the connection of the original proxy - self.__conn = connection - elif self.__url.scheme == 'https': - self.__conn = httplib.HTTPSConnection(self.__url.hostname, port, - None, None, False, - timeout) - else: - self.__conn = httplib.HTTPConnection(self.__url.hostname, port, - False, timeout) - - def __getattr__(self, name): - if name.startswith('__') and name.endswith('__'): - # Python internal stuff - raise AttributeError - if self.__service_name is not None: - name = "%s.%s" % (self.__service_name, name) - return AuthServiceProxy(self.__service_url, name, connection=self.__conn) - - def __call__(self, *args): - self.__id_count += 1 - - postdata = json.dumps({'version': '1.1', - 'method': self.__service_name, - 'params': args, - 'id': self.__id_count}) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - - response = self._get_response() - if response['error'] is not None: - raise JSONRPCException(response['error']) - elif 'result' not in response: - raise JSONRPCException({ - 'code': -343, 'message': 'missing JSON-RPC result'}) - else: - return response['result'] - - def _batch(self, rpc_call_list): - postdata = json.dumps(list(rpc_call_list)) - self.__conn.request('POST', self.__url.path, postdata, - {'Host': self.__url.hostname, - 'User-Agent': USER_AGENT, - 'Authorization': self.__auth_header, - 'Content-type': 'application/json'}) - - return self._get_response() - - def _get_response(self): - http_response = self.__conn.getresponse() - if http_response is None: - raise JSONRPCException({ - 'code': -342, 'message': 'missing HTTP response from server'}) - - return json.loads(http_response.read().decode('utf8'), - parse_float=decimal.Decimal) diff --git a/doc/build-unix.md b/doc/build-unix.md index 70a7616f50..341b17b543 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -46,7 +46,7 @@ Licenses of statically linked libraries: - GCC 4.3.3 - OpenSSL 1.0.1c - Berkeley DB 4.8.30.NC -- Boost 1.37 +- Boost 1.55 - miniupnpc 1.6 - qt 4.8.3 - protobuf 2.5.0 @@ -72,9 +72,10 @@ for Ubuntu 12.04 and later: Ubuntu 12.04 and later have packages for libdb5.1-dev and libdb5.1++-dev, but using these will break binary wallet compatibility, and is not recommended. - -for Ubuntu 13.10: - libboost1.54-all-dev will not work. Remove libboost1.54-all-dev and install libboost1.53-all-dev + +for Ubuntu 13.10: + libboost1.54 will not work, + remove libboost1.54-all-dev and install libboost1.53-all-dev instead. for Debian 7 (Wheezy) and later: The oldstable repository contains db4.8 packages. @@ -82,7 +83,7 @@ for Debian 7 (Wheezy) and later: replacing [mirror] with any official debian mirror. deb http://[mirror]/debian/ oldstable main - + To enable the change run sudo apt-get update @@ -91,8 +92,7 @@ for other Ubuntu & Debian: sudo apt-get install libdb4.8-dev sudo apt-get install libdb4.8++-dev - sudo apt-get install libboost1.37-dev - (If using Boost 1.37, append -mt to the boost libraries in the makefile) + sudo apt-get install libboost1.55-all-dev Optional: diff --git a/jsonrpc/__init__.py b/jsonrpc/__init__.py deleted file mode 100644 index 8441fa3120..0000000000 --- a/jsonrpc/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from .json import loads, dumps, JSONEncodeException, JSONDecodeException -from jsonrpc.proxy import ServiceProxy, JSONRPCException diff --git a/jsonrpc/authproxy.py b/jsonrpc/authproxy.py deleted file mode 100644 index e90ef361d0..0000000000 --- a/jsonrpc/authproxy.py +++ /dev/null @@ -1,3 +0,0 @@ -from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException - -__all__ = ['AuthServiceProxy', 'JSONRPCException'] diff --git a/jsonrpc/json.py b/jsonrpc/json.py deleted file mode 100644 index 95398630f7..0000000000 --- a/jsonrpc/json.py +++ /dev/null @@ -1,9 +0,0 @@ -_json = __import__('json') -loads = _json.loads -dumps = _json.dumps -if hasattr(_json, 'JSONEncodeException'): - JSONEncodeException = _json.JSONEncodeException - JSONDecodeException = _json.JSONDecodeException -else: - JSONEncodeException = TypeError - JSONDecodeException = ValueError diff --git a/jsonrpc/proxy.py b/jsonrpc/proxy.py deleted file mode 100644 index 0d2be1e93b..0000000000 --- a/jsonrpc/proxy.py +++ /dev/null @@ -1 +0,0 @@ -from bitcoinrpc.authproxy import AuthServiceProxy as ServiceProxy, JSONRPCException diff --git a/setup.py b/setup.py deleted file mode 100644 index b5a217bf93..0000000000 --- a/setup.py +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env python - -from distutils.core import setup - -setup(name='python-bitcoinrpc', - version='0.1', - description='Enhanced version of python-jsonrpc for use with Bitcoin', - long_description=open('README').read(), - author='Jeff Garzik', - author_email='<jgarzik@exmulti.com>', - maintainer='Jeff Garzik', - maintainer_email='<jgarzik@exmulti.com>', - url='http://www.github.com/jgarzik/python-bitcoinrpc', - packages=['bitcoinrpc'], - classifiers=['License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', 'Operating System :: OS Independent']) diff --git a/src/m4/bitcoin_qt.m4 b/src/m4/bitcoin_qt.m4 index 068371e83a..e71ecd7172 100644 --- a/src/m4/bitcoin_qt.m4 +++ b/src/m4/bitcoin_qt.m4 @@ -124,12 +124,12 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ if test x$have_qt_test = xno; then bitcoin_enable_qt_test=no fi - bitcoin_enable_qt_dbus=yes - if test x$have_qt_dbus = xno; then - bitcoin_enable_qt_dbus=no - if test x$use_dbus = xyes; then - AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.") - fi + bitcoin_enable_qt_dbus=no + if test x$use_dbus != xno && test x$have_qt_dbus = xyes; then + bitcoin_enable_qt_dbus=yes + fi + if test x$use_dbus = xyes && test x$have_qt_dbus = xno; then + AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.") fi if test x$LUPDATE == x; then AC_MSG_WARN("lupdate is required to update qt translations") diff --git a/src/main.cpp b/src/main.cpp index 5f50e05780..836c86483a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1823,7 +1823,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C return state.DoS(100, error("ConnectBlock() : coinbase pays too much (actual=%d vs limit=%d)", block.vtx[0].GetValueOut(), GetBlockValue(pindex->nHeight, nFees)), - REJECT_INVALID, "bad-cb-amount"); + REJECT_INVALID, "bad-cb-amount"); if (!control.Wait()) return state.DoS(100, false); @@ -3244,14 +3244,14 @@ void static ProcessGetData(CNode* pfrom) int nHeight = mi->second->nHeight; CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(mapBlockIndex); if (pcheckpoint && nHeight < pcheckpoint->nHeight) { - if (!chainActive.Contains(mi->second)) - { - LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n"); - } else { - send = true; - } + if (!chainActive.Contains(mi->second)) + { + LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n"); + } else { + send = true; + } } else { - send = true; + send = true; } } if (send) @@ -3759,7 +3759,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv) } int nDoS = 0; if (state.IsInvalid(nDoS)) - { + { LogPrint("mempool", "%s from %s %s was not accepted into the memory pool: %s\n", tx.GetHash().ToString(), pfrom->addr.ToString(), pfrom->cleanSubVer, state.GetRejectReason()); diff --git a/src/main.h b/src/main.h index b9c8dd7050..5ecf9d8365 100644 --- a/src/main.h +++ b/src/main.h @@ -427,6 +427,7 @@ class CMerkleTx : public CTransaction { private: int GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const; + public: uint256 hashBlock; std::vector<uint256> vMerkleBranch; diff --git a/src/qt/addresstablemodel.cpp b/src/qt/addresstablemodel.cpp index 2987e5fdda..dfbd445ce3 100644 --- a/src/qt/addresstablemodel.cpp +++ b/src/qt/addresstablemodel.cpp @@ -114,7 +114,7 @@ public: case CT_NEW: if(inModel) { - qDebug() << "AddressTablePriv::updateEntry : Warning: Got CT_NOW, but entry is already in model"; + qDebug() << "AddressTablePriv::updateEntry : Warning: Got CT_NEW, but entry is already in model"; break; } parent->beginInsertRows(QModelIndex(), lowerIndex, lowerIndex); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 0ca16edb8c..da7762282a 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -673,17 +673,27 @@ void BitcoinGUI::setNumBlocks(int count, int nTotalBlocks) { // Represent time from last generated block in human readable text QString timeBehindText; - if(secs < 48*60*60) + const int HOUR_IN_SECONDS = 60*60; + const int DAY_IN_SECONDS = 24*60*60; + const int WEEK_IN_SECONDS = 7*24*60*60; + const int YEAR_IN_SECONDS = 31556952; // Average length of year in Gregorian calendar + if(secs < 2*DAY_IN_SECONDS) { - timeBehindText = tr("%n hour(s)","",secs/(60*60)); + timeBehindText = tr("%n hour(s)","",secs/HOUR_IN_SECONDS); } - else if(secs < 14*24*60*60) + else if(secs < 2*WEEK_IN_SECONDS) { - timeBehindText = tr("%n day(s)","",secs/(24*60*60)); + timeBehindText = tr("%n day(s)","",secs/DAY_IN_SECONDS); + } + else if(secs < YEAR_IN_SECONDS) + { + timeBehindText = tr("%n week(s)","",secs/WEEK_IN_SECONDS); } else { - timeBehindText = tr("%n week(s)","",secs/(7*24*60*60)); + int years = secs / YEAR_IN_SECONDS; + int remainder = secs % YEAR_IN_SECONDS; + timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS)); } progressBarLabel->setVisible(true); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 1e5a2efc94..9df8f180b1 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -18,7 +18,6 @@ #include <QApplication> #include <QCheckBox> -#include <QColor> #include <QCursor> #include <QDialogButtonBox> #include <QFlags> @@ -386,6 +385,18 @@ void CoinControlDialog::viewItemChanged(QTreeWidgetItem* item, int column) if (ui->treeWidget->isEnabled()) // do not update on every click for (un)select all CoinControlDialog::updateLabels(model, this); } + + // todo: this is a temporary qt5 fix: when clicking a parent node in tree mode, the parent node + // including all childs are partially selected. But the parent node should be fully selected + // as well as the childs. Childs should never be partially selected in the first place. + // Please remove this ugly fix, once the bug is solved upstream. +#if QT_VERSION >= 0x050000 + else if (column == COLUMN_CHECKBOX && item->childCount() > 0) + { + if (item->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked && item->child(0)->checkState(COLUMN_CHECKBOX) == Qt::PartiallyChecked) + item->setCheckState(COLUMN_CHECKBOX, Qt::Checked); + } +#endif } // return human readable label for priority number @@ -662,9 +673,6 @@ void CoinControlDialog::updateView() itemWalletAddress->setFlags(flgTristate); itemWalletAddress->setCheckState(COLUMN_CHECKBOX,Qt::Unchecked); - for (int i = 0; i < ui->treeWidget->columnCount(); i++) - itemWalletAddress->setBackground(i, QColor(248, 247, 246)); - // label itemWalletAddress->setText(COLUMN_LABEL, sWalletLabel); diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui index 3e1a8bccc7..e1a0a28f81 100644 --- a/src/qt/forms/receivecoinsdialog.ui +++ b/src/qt/forms/receivecoinsdialog.ui @@ -263,6 +263,9 @@ <property name="text"> <string>Show</string> </property> + <property name="enabled"> + <bool>false</bool> + </property> <property name="icon"> <iconset resource="../bitcoin.qrc"> <normaloff>:/icons/edit</normaloff>:/icons/edit</iconset> @@ -277,6 +280,9 @@ <property name="text"> <string>Remove</string> </property> + <property name="enabled"> + <bool>false</bool> + </property> <property name="icon"> <iconset resource="../bitcoin.qrc"> <normaloff>:/icons/remove</normaloff>:/icons/remove</iconset> diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 628847e030..ebcfde35c4 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -637,6 +637,19 @@ This product includes software developed by the OpenSSL Project for use in the O </translation> </message> <message> + <location line="+0"/> + <source>%1 and %2</source> + <translation type="unfinished"></translation> + </message> + <message numerus="yes"> + <location line="+0"/> + <source>%n year(s)</source> + <translation type="unfinished"> + <numerusform>%n year</numerusform> + <numerusform>%n years</numerusform> + </translation> + </message> + <message> <location line="+4"/> <source>%1 behind</source> <translation>%1 behind</translation> diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 3b83a5ff62..b61fdd2301 100644 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -30,6 +30,11 @@ OptionsModel::OptionsModel(QObject *parent) : Init(); } +void OptionsModel::addOverriddenOption(const std::string &option) +{ + strOverriddenByCommandLine += QString::fromStdString(option) + "=" + QString::fromStdString(mapArgs[option]) + " "; +} + // Writes all missing QSettings with their default values void OptionsModel::Init() { @@ -76,23 +81,23 @@ void OptionsModel::Init() settings.setValue("nTransactionFee", 0); nTransactionFee = settings.value("nTransactionFee").toLongLong(); // if -paytxfee is set, this will be overridden later in init.cpp if (mapArgs.count("-paytxfee")) - strOverriddenByCommandLine += "-paytxfee "; + addOverriddenOption("-paytxfee"); if (!settings.contains("bSpendZeroConfChange")) settings.setValue("bSpendZeroConfChange", true); if (!SoftSetBoolArg("-spendzeroconfchange", settings.value("bSpendZeroConfChange").toBool())) - strOverriddenByCommandLine += "-spendzeroconfchange "; + addOverriddenOption("-spendzeroconfchange"); #endif if (!settings.contains("nDatabaseCache")) settings.setValue("nDatabaseCache", (qint64)nDefaultDbCache); if (!SoftSetArg("-dbcache", settings.value("nDatabaseCache").toString().toStdString())) - strOverriddenByCommandLine += "-dbcache "; + addOverriddenOption("-dbcache"); if (!settings.contains("nThreadsScriptVerif")) settings.setValue("nThreadsScriptVerif", 0); if (!SoftSetArg("-par", settings.value("nThreadsScriptVerif").toString().toStdString())) - strOverriddenByCommandLine += "-par "; + addOverriddenOption("-par"); // Network if (!settings.contains("fUseUPnP")) @@ -100,9 +105,9 @@ void OptionsModel::Init() settings.setValue("fUseUPnP", true); #else settings.setValue("fUseUPnP", false); -#endif +#endif if (!SoftSetBoolArg("-upnp", settings.value("fUseUPnP").toBool())) - strOverriddenByCommandLine += "-upnp "; + addOverriddenOption("-upnp"); if (!settings.contains("fUseProxy")) settings.setValue("fUseProxy", false); @@ -110,18 +115,18 @@ void OptionsModel::Init() settings.setValue("addrProxy", "127.0.0.1:9050"); // Only try to set -proxy, if user has enabled fUseProxy if (settings.value("fUseProxy").toBool() && !SoftSetArg("-proxy", settings.value("addrProxy").toString().toStdString())) - strOverriddenByCommandLine += "-proxy "; + addOverriddenOption("-proxy"); if (!settings.contains("nSocksVersion")) settings.setValue("nSocksVersion", 5); // Only try to set -socks, if user has enabled fUseProxy if (settings.value("fUseProxy").toBool() && !SoftSetArg("-socks", settings.value("nSocksVersion").toString().toStdString())) - strOverriddenByCommandLine += "-socks "; + addOverriddenOption("-socks"); // Display if (!settings.contains("language")) settings.setValue("language", ""); if (!SoftSetArg("-lang", settings.value("language").toString().toStdString())) - strOverriddenByCommandLine += "-lang"; + addOverriddenOption("-lang"); language = settings.value("language").toString(); } diff --git a/src/qt/optionsmodel.h b/src/qt/optionsmodel.h index a3487ddd2e..ece5ef78a4 100644 --- a/src/qt/optionsmodel.h +++ b/src/qt/optionsmodel.h @@ -75,6 +75,9 @@ private: /* settings that were overriden by command-line */ QString strOverriddenByCommandLine; + /// Add option to list of GUI options overridden through command line/config file + void addOverriddenOption(const std::string &option); + signals: void displayUnitChanged(int unit); void transactionFeeChanged(qint64); diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp index 7539645b47..2af3949ae4 100644 --- a/src/qt/receivecoinsdialog.cpp +++ b/src/qt/receivecoinsdialog.cpp @@ -19,6 +19,7 @@ #include <QMessageBox> #include <QTextDocument> #include <QScrollBar> +#include <QItemSelection> ReceiveCoinsDialog::ReceiveCoinsDialog(QWidget *parent) : QDialog(parent), @@ -77,6 +78,11 @@ void ReceiveCoinsDialog::setModel(WalletModel *model) ui->recentRequestsView->horizontalHeader()->resizeSection(RecentRequestsTableModel::Amount, 100); model->getRecentRequestsTableModel()->sort(RecentRequestsTableModel::Date, Qt::DescendingOrder); + + connect(ui->recentRequestsView->selectionModel(), + SIGNAL(selectionChanged(QItemSelection, QItemSelection)), + this, + SLOT(on_recentRequestsView_selectionChanged(QItemSelection, QItemSelection))); } } @@ -161,6 +167,15 @@ void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex & dialog->show(); } +void ReceiveCoinsDialog::on_recentRequestsView_selectionChanged(const QItemSelection &selected, + const QItemSelection &deselected) +{ + // Enable Show/Remove buttons only if anything is selected. + bool enable = !ui->recentRequestsView->selectionModel()->selectedRows().isEmpty(); + ui->showRequestButton->setEnabled(enable); + ui->removeRequestButton->setEnabled(enable); +} + void ReceiveCoinsDialog::on_showRequestButton_clicked() { if(!model || !model->getRecentRequestsTableModel() || !ui->recentRequestsView->selectionModel()) diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h index 12d2235782..bfe8b3401f 100644 --- a/src/qt/receivecoinsdialog.h +++ b/src/qt/receivecoinsdialog.h @@ -10,6 +10,7 @@ #include <QMenu> #include <QPoint> #include <QVariant> +#include <QItemSelection> namespace Ui { class ReceiveCoinsDialog; @@ -51,6 +52,7 @@ private slots: void on_showRequestButton_clicked(); void on_removeRequestButton_clicked(); void on_recentRequestsView_doubleClicked(const QModelIndex &index); + void on_recentRequestsView_selectionChanged(const QItemSelection &, const QItemSelection &); void updateDisplayUnit(); void showMenu(const QPoint &); void copyLabel(); diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 353fb77b88..aa17590431 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -46,8 +46,9 @@ Value getinfo(const Array& params, bool fHelp) " \"testnet\": true|false, (boolean) if the server is using testnet or not\n" " \"keypoololdest\": xxxxxx, (numeric) the timestamp (seconds since GMT epoch) of the oldest pre-generated key in the key pool\n" " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" - " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" + " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in btc/kb\n" + " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in btc/kb\n" " \"errors\": \"...\" (string) any error messages\n" "}\n" "\nExamples:\n" @@ -78,10 +79,11 @@ Value getinfo(const Array& params, bool fHelp) obj.push_back(Pair("keypoololdest", (boost::int64_t)pwalletMain->GetOldestKeyPoolTime())); obj.push_back(Pair("keypoolsize", (int)pwalletMain->GetKeyPoolSize())); } - obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); if (pwalletMain && pwalletMain->IsCrypted()) obj.push_back(Pair("unlocked_until", (boost::int64_t)nWalletUnlockTime)); + obj.push_back(Pair("paytxfee", ValueFromAmount(nTransactionFee))); #endif + obj.push_back(Pair("relayfee", ValueFromAmount(CTransaction::nMinRelayTxFee))); obj.push_back(Pair("errors", GetWarnings("statusbar"))); return obj; } diff --git a/src/test/checkblock_tests.cpp b/src/test/checkblock_tests.cpp index d47a33fd46..67503b200b 100644 --- a/src/test/checkblock_tests.cpp +++ b/src/test/checkblock_tests.cpp @@ -15,8 +15,7 @@ BOOST_AUTO_TEST_SUITE(CheckBlock_tests) -bool -read_block(const std::string& filename, CBlock& block) +bool read_block(const std::string& filename, CBlock& block) { namespace fs = boost::filesystem; fs::path testFile = fs::current_path() / "data" / filename; diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 761cc4a008..8cb365a46f 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -325,5 +325,7 @@ ["NOP1 0x01 1", "HASH160 0x14 0xda1745e9b549bd0bfa1a569971c77eba30cd5a4b EQUAL"], ["0 0x01 0x50", "HASH160 0x14 0xece424a6bb6ddf4db592c0faed60685047a361b1 EQUAL", "OP_RESERVED in P2SH should fail"], -["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "OP_VER in P2SH should fail"] +["0 0x01 VER", "HASH160 0x14 0x0f4d7845db968f2a81b530b6f3c1d6246d4c7e01 EQUAL", "OP_VER in P2SH should fail"], + +["0x00", "'00' EQUAL", "Basic OP_0 execution"] ] diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index e4c181cae8..3b4c191865 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -411,5 +411,7 @@ ["0x4c 0x40 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242", "0x4d 0x4000 0x42424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242424242 EQUAL", -"Basic PUSHDATA1 signedness check"] +"Basic PUSHDATA1 signedness check"], + +["0x00", "SIZE 0 EQUAL", "Basic OP_0 execution"] ] diff --git a/src/wallet.cpp b/src/wallet.cpp index 4f7b96e7f2..df1eb549ad 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -589,7 +589,7 @@ bool CWallet::AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet) bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& tx, const CBlock* pblock, bool fUpdate) { { - LOCK(cs_wallet); + AssertLockHeld(cs_wallet); bool fExisted = mapWallet.count(hash); if (fExisted && !fUpdate) return false; if (fExisted || IsMine(tx) || IsFromMe(tx)) @@ -606,9 +606,8 @@ bool CWallet::AddToWalletIfInvolvingMe(const uint256 &hash, const CTransaction& void CWallet::SyncTransaction(const uint256 &hash, const CTransaction& tx, const CBlock* pblock) { - AddToWalletIfInvolvingMe(hash, tx, pblock, true); - - if (mapWallet.count(hash) == 0) + LOCK(cs_wallet); + if (!AddToWalletIfInvolvingMe(hash, tx, pblock, true)) return; // Not one of ours // If a transaction changes 'conflicted' state, that changes the balance |