diff options
Diffstat (limited to 'src')
34 files changed, 613 insertions, 540 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 727a88c3e7..2c00f8b572 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,4 +1,3 @@ -AM_CPPFLAGS = $(INCLUDES) AM_LDFLAGS = $(PTHREAD_CFLAGS) $(LIBTOOL_LDFLAGS) if USE_LIBSECP256K1 @@ -22,7 +21,7 @@ $(LIBLEVELDB) $(LIBMEMENV): endif BITCOIN_CONFIG_INCLUDES=-I$(builddir)/config -BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) +BITCOIN_INCLUDES=-I$(builddir) -I$(builddir)/obj $(BOOST_CPPFLAGS) $(LEVELDB_CPPFLAGS) $(CRYPTO_CFLAGS) $(SSL_CFLAGS) if USE_LIBSECP256K1 BITCOIN_INCLUDES += -I$(srcdir)/secp256k1/include @@ -230,6 +229,7 @@ libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp endif # cli: shared between bitcoin-cli and bitcoin-qt +libbitcoin_cli_a_CPPFLAGS = $(BITCOIN_INCLUDES) libbitcoin_cli_a_SOURCES = \ rpcclient.cpp \ $(BITCOIN_CORE_H) @@ -261,8 +261,9 @@ if TARGET_WINDOWS bitcoind_SOURCES += bitcoind-res.rc endif -bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) +bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) +bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) # bitcoin-cli binary # bitcoin_cli_LDADD = \ @@ -270,7 +271,10 @@ bitcoin_cli_LDADD = \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ $(LIBBITCOIN_CRYPTO) \ - $(BOOST_LIBS) + $(BOOST_LIBS) \ + $(SSL_LIBS) \ + $(CRYPTO_LIBS) + bitcoin_cli_SOURCES = \ bitcoin-cli.cpp @@ -285,15 +289,24 @@ bitcoin_tx_LDADD = \ $(LIBBITCOIN_UNIVALUE) \ $(LIBBITCOIN_COMMON) \ $(LIBBITCOIN_UTIL) \ - $(LIBBITCOIN_CRYPTO) \ - $(BOOST_LIBS) + $(LIBBITCOIN_CRYPTO) + +if USE_LIBSECP256K1 + bitcoin_tx_LDADD += secp256k1/libsecp256k1.la +endif + + bitcoin_tx_LDADD += $(BOOST_LIBS) \ + $(SSL_LIBS) \ + $(CRYPTO_LIBS) bitcoin_tx_SOURCES = bitcoin-tx.cpp bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) # +bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) if TARGET_WINDOWS bitcoin_cli_SOURCES += bitcoin-cli-res.rc endif +bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 2052264dc9..28d7053fc4 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -245,8 +245,6 @@ RES_ICONS = \ qt/res/icons/remove.png \ qt/res/icons/send.png \ qt/res/icons/synced.png \ - qt/res/icons/toolbar.png \ - qt/res/icons/toolbar_testnet.png \ qt/res/icons/transaction0.png \ qt/res/icons/transaction2.png \ qt/res/icons/transaction_conflicted.png \ @@ -360,11 +358,11 @@ if ENABLE_WALLET qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) endif qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ - $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) + $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) if USE_LIBSECP256K1 qt_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la endif -qt_bitcoin_qt_LDFLAGS = $(AM_LDFLAGS) $(QT_LDFLAGS) +qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) #locale/foo.ts -> locale/foo.qm QT_QM=$(QT_TS:.ts=.qm) diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index d49b2240ea..2cba5b7e1e 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -32,11 +32,11 @@ qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) endif qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ - $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) + $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) if USE_LIBSECP256K1 qt_test_test_bitcoin_qt_LDADD += secp256k1/libsecp256k1.la endif -qt_test_test_bitcoin_qt_LDFLAGS = $(AM_LDFLAGS) $(QT_LDFLAGS) +qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 72451fba9a..b54c9be664 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -74,7 +74,8 @@ if USE_LIBSECP256K1 test_test_bitcoin_LDADD += secp256k1/libsecp256k1.la endif -test_test_bitcoin_LDADD += $(BDB_LIBS) +test_test_bitcoin_LDADD += $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) +test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp index 299315424b..ffe87298f6 100644 --- a/src/bitcoin-tx.cpp +++ b/src/bitcoin-tx.cpp @@ -283,12 +283,12 @@ static const struct { const char *flagStr; int flags; } sighashOptions[N_SIGHASH_OPTS] = { - "ALL", SIGHASH_ALL, - "NONE", SIGHASH_NONE, - "SINGLE", SIGHASH_SINGLE, - "ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY, - "NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY, - "SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY, + {"ALL", SIGHASH_ALL}, + {"NONE", SIGHASH_NONE}, + {"SINGLE", SIGHASH_SINGLE}, + {"ALL|ANYONECANPAY", SIGHASH_ALL|SIGHASH_ANYONECANPAY}, + {"NONE|ANYONECANPAY", SIGHASH_NONE|SIGHASH_ANYONECANPAY}, + {"SINGLE|ANYONECANPAY", SIGHASH_SINGLE|SIGHASH_ANYONECANPAY}, }; static bool findSighashFlags(int& flags, const string& flagStr) diff --git a/src/coins.h b/src/coins.h index 9f90fe6bd0..ff60288163 100644 --- a/src/coins.h +++ b/src/coins.h @@ -247,7 +247,10 @@ private: public: CCoinsKeyHasher(); - uint64_t operator()(const uint256& key) const { + // This *must* return size_t. With Boost 1.46 on 32-bit systems the + // unordered_map will behave unpredictably if the custom hasher returns a + // uint64_t, resulting in failures when syncing the chain (#4634). + size_t operator()(const uint256& key) const { return key.GetHash(salt); } }; diff --git a/src/compat.h b/src/compat.h index 1b3a60d11b..52c7817130 100644 --- a/src/compat.h +++ b/src/compat.h @@ -1,5 +1,5 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -59,4 +59,4 @@ typedef u_int SOCKET; #define SOCKET_ERROR -1 #endif -#endif +#endif // _BITCOIN_COMPAT_H diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp index 417166aeda..cbe059735b 100644 --- a/src/compat/glibcxx_compat.cpp +++ b/src/compat/glibcxx_compat.cpp @@ -64,6 +64,8 @@ template istream& istream::_M_extract(unsigned short&); out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT { } +length_error::~length_error() _GLIBCXX_USE_NOEXCEPT { } + // Used with permission. // See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d diff --git a/src/keystore.h b/src/keystore.h index 72411a1387..6a3a0dc13e 100644 --- a/src/keystore.h +++ b/src/keystore.h @@ -8,21 +8,12 @@ #include "key.h" #include "sync.h" -#include "script.h" // for CNoDestination #include <boost/signals2/signal.hpp> #include <boost/variant.hpp> class CScript; -/** A txout script template with a specific destination. It is either: - * * CNoDestination: no destination set - * * CKeyID: TX_PUBKEYHASH destination - * * CScriptID: TX_SCRIPTHASH destination - * A CTxDestination is the internal data type encoded in a CBitcoinAddress - */ -typedef boost::variant<CNoDestination, CKeyID, CScriptID> CTxDestination; - /** A virtual base class for key stores */ class CKeyStore { diff --git a/src/m4/bitcoin_find_bdb48.m4 b/src/m4/bitcoin_find_bdb48.m4 index 72ec49b635..5223163fe5 100644 --- a/src/m4/bitcoin_find_bdb48.m4 +++ b/src/m4/bitcoin_find_bdb48.m4 @@ -44,7 +44,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ AC_ARG_WITH([incompatible-bdb],[AS_HELP_STRING([--with-incompatible-bdb], [allow using a bdb version other than 4.8])],[ AC_MSG_WARN([Found Berkeley DB other than 4.8; wallets opened by this build will not be portable!]) ],[ - AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore)]) + AC_MSG_ERROR([Found Berkeley DB other than 4.8, required for portable wallets (--with-incompatible-bdb to ignore or --disable-wallet to disable wallet functionality)]) ]) else BITCOIN_SUBDIR_TO_INCLUDE(BDB_CPPFLAGS,[${bdb48path}],db_cxx) @@ -60,7 +60,7 @@ AC_DEFUN([BITCOIN_FIND_BDB48],[ ]) done if test "x$BDB_LIBS" = "x"; then - AC_MSG_ERROR(libdb_cxx missing) + AC_MSG_ERROR([libdb_cxx missing, Bitcoin Core requires this library for wallet functionality (--disable-wallet to disable wallet functionality)]) fi AC_SUBST(BDB_LIBS) ]) diff --git a/src/main.cpp b/src/main.cpp index ba521b6b19..e135e93adb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -956,9 +956,18 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa if (Params().RequireStandard() && !AreInputsStandard(tx, view)) return error("AcceptToMemoryPool: : nonstandard transaction input"); - // Note: if you modify this code to accept non-standard transactions, then - // you should add code here to check that the transaction does a - // reasonable number of ECDSA signature verifications. + // Check that the transaction doesn't have an excessive number of + // sigops, making it impossible to mine. Since the coinbase transaction + // itself can contain sigops MAX_TX_SIGOPS is less than + // MAX_BLOCK_SIGOPS; we still consider this an invalid rather than + // merely non-standard transaction. + unsigned int nSigOps = GetLegacySigOpCount(tx); + nSigOps += GetP2SHSigOpCount(tx, view); + if (nSigOps > MAX_TX_SIGOPS) + return state.DoS(0, + error("AcceptToMemoryPool : too many sigops %s, %d > %d", + hash.ToString(), nSigOps, MAX_TX_SIGOPS), + REJECT_NONSTANDARD, "bad-txns-too-many-sigops"); int64_t nValueOut = tx.GetValueOut(); int64_t nFees = nValueIn-nValueOut; @@ -3052,7 +3061,7 @@ bool CVerifyDB::VerifyDB(int nCheckLevel, int nCheckDepth) } } // check level 3: check for inconsistencies during memory-only disconnect of tip blocks - if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= 2*nCoinCacheSize + 32000) { + if (nCheckLevel >= 3 && pindex == pindexState && (coins.GetCacheSize() + pcoinsTip->GetCacheSize()) <= nCoinCacheSize) { bool fClean = true; if (!DisconnectBlock(block, state, pindex, coins, &fClean)) return error("VerifyDB() : *** irrecoverable inconsistency in block data at %d, hash=%s", pindex->nHeight, pindex->GetBlockHash().ToString()); diff --git a/src/main.h b/src/main.h index a27020459a..01d3f119e1 100644 --- a/src/main.h +++ b/src/main.h @@ -45,6 +45,8 @@ static const unsigned int MAX_STANDARD_TX_SIZE = 100000; static const unsigned int MAX_BLOCK_SIGOPS = MAX_BLOCK_SIZE/50; /** Maxiumum number of signature check operations in an IsStandard() P2SH script */ static const unsigned int MAX_P2SH_SIGOPS = 15; +/** The maximum number of sigops we're willing to relay/mine in a single tx */ +static const unsigned int MAX_TX_SIGOPS = MAX_BLOCK_SIGOPS/5; /** The maximum number of orphan transactions kept in memory */ static const unsigned int MAX_ORPHAN_TRANSACTIONS = MAX_BLOCK_SIZE/100; /** Default for -maxorphanblocks, maximum number of orphan blocks kept in memory */ diff --git a/src/miner.cpp b/src/miner.cpp index ec56c71192..9408d2c5aa 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -402,17 +402,8 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey) return CreateNewBlock(scriptPubKey); } -bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) +bool ProcessBlockFound(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey) { - uint256 hash = pblock->GetHash(); - uint256 hashTarget = uint256().SetCompact(pblock->nBits); - - if (hash > hashTarget) - return false; - - //// debug print - LogPrintf("BitcoinMiner:\n"); - LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); pblock->print(); LogPrintf("generated %s\n", FormatMoney(pblock->vtx[0].vout[0].nValue)); @@ -500,7 +491,9 @@ void static BitcoinMiner(CWallet *pwallet) assert(hash == pblock->GetHash()); SetThreadPriority(THREAD_PRIORITY_NORMAL); - CheckWork(pblock, *pwallet, reservekey); + LogPrintf("BitcoinMiner:\n"); + LogPrintf("proof-of-work found \n hash: %s \ntarget: %s\n", hash.GetHex(), hashTarget.GetHex()); + ProcessBlockFound(pblock, *pwallet, reservekey); SetThreadPriority(THREAD_PRIORITY_LOWEST); // In regression test mode, stop mining after a block is found. diff --git a/src/net.cpp b/src/net.cpp index 62124514c8..ec58f84b06 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -368,7 +368,7 @@ bool GetMyExternalIP(CNetAddr& ipRet) const char* pszKeyword; for (int nLookup = 0; nLookup <= 1; nLookup++) - for (int nHost = 1; nHost <= 2; nHost++) + for (int nHost = 1; nHost <= 1; nHost++) { // We should be phasing out our use of sites like these. If we need // replacements, we should ask for volunteers to put this simple @@ -393,25 +393,6 @@ bool GetMyExternalIP(CNetAddr& ipRet) pszKeyword = "Address:"; } - else if (nHost == 2) - { - addrConnect = CService("74.208.43.192", 80); // www.showmyip.com - - if (nLookup == 1) - { - CService addrIP("www.showmyip.com", 80, true); - if (addrIP.IsValid()) - addrConnect = addrIP; - } - - pszGet = "GET /simple/ HTTP/1.1\r\n" - "Host: www.showmyip.com\r\n" - "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n" - "Connection: close\r\n" - "\r\n"; - - pszKeyword = NULL; // Returns just IP address - } if (GetMyExternalIP2(addrConnect, pszGet, pszKeyword, ipRet)) return true; @@ -356,12 +356,11 @@ public: ~CNode() { - if (hSocket != INVALID_SOCKET) - { - CloseSocket(hSocket); - } + CloseSocket(hSocket); + if (pfilter) delete pfilter; + GetNodeSignals().FinalizeNode(GetId()); } diff --git a/src/netbase.cpp b/src/netbase.cpp index af6d11f0e2..1031e7e38a 100644 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -334,6 +334,7 @@ bool static ConnectSocketDirectly(const CService &addrConnect, SOCKET& hSocketRe #ifdef SO_NOSIGPIPE int set = 1; + // Different way of disabling SIGPIPE on BSD setsockopt(hSocket, SOL_SOCKET, SO_NOSIGPIPE, (void*)&set, sizeof(int)); #endif diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index ea706d9f25..a43e7cb756 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -489,6 +489,9 @@ int main(int argc, char *argv[]) Q_INIT_RESOURCE(bitcoin); Q_INIT_RESOURCE(bitcoin_locale); + + GUIUtil::SubstituteFonts(); + BitcoinApplication app(argc, argv); #if QT_VERSION > 0x050100 // Generate high-dpi pixmaps diff --git a/src/qt/bitcoin.qrc b/src/qt/bitcoin.qrc index 357c6470d3..6dba62035b 100644 --- a/src/qt/bitcoin.qrc +++ b/src/qt/bitcoin.qrc @@ -4,7 +4,6 @@ <file alias="address-book">res/icons/address-book.png</file> <file alias="quit">res/icons/quit.png</file> <file alias="send">res/icons/send.png</file> - <file alias="toolbar">res/icons/toolbar.png</file> <file alias="connect_0">res/icons/connect0_16.png</file> <file alias="connect_1">res/icons/connect1_16.png</file> <file alias="connect_2">res/icons/connect2_16.png</file> @@ -24,7 +23,6 @@ <file alias="editcopy">res/icons/editcopy.png</file> <file alias="add">res/icons/add.png</file> <file alias="bitcoin_testnet">res/icons/bitcoin_testnet.png</file> - <file alias="toolbar_testnet">res/icons/toolbar_testnet.png</file> <file alias="edit">res/icons/edit.png</file> <file alias="history">res/icons/history.png</file> <file alias="overview">res/icons/overview.png</file> diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index e3257e859c..bfca5e8d1a 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -479,12 +479,12 @@ void BitcoinGUI::createTrayIcon(bool fIsTestnet) if (!fIsTestnet) { trayIcon->setToolTip(tr("Bitcoin Core client")); - trayIcon->setIcon(QIcon(":/icons/toolbar")); + trayIcon->setIcon(QIcon(":/icons/bitcoin")); } else { trayIcon->setToolTip(tr("Bitcoin Core client") + " " + tr("[testnet]")); - trayIcon->setIcon(QIcon(":/icons/toolbar_testnet")); + trayIcon->setIcon(QIcon(":/icons/bitcoin_testnet")); } trayIcon->show(); diff --git a/src/qt/forms/overviewpage.ui b/src/qt/forms/overviewpage.ui index df16295f77..7784a862d7 100644 --- a/src/qt/forms/overviewpage.ui +++ b/src/qt/forms/overviewpage.ui @@ -13,8 +13,8 @@ <property name="windowTitle"> <string>Form</string> </property> - <layout class="QVBoxLayout" name="topLayout"> - <item> + <layout class="QFormLayout" name="formLayout_3"> + <item row="0" column="0" colspan="2"> <widget class="QLabel" name="labelAlerts"> <property name="visible"> <bool>false</bool> @@ -30,7 +30,7 @@ </property> </widget> </item> - <item> + <item row="1" column="1"> <layout class="QHBoxLayout" name="horizontalLayout" stretch="1,1"> <item> <layout class="QVBoxLayout" name="verticalLayout_2"> @@ -46,374 +46,344 @@ <item> <layout class="QHBoxLayout" name="horizontalLayout_4"> <item> - <layout class="QHBoxLayout" name="horizontalLayout_7"> - <item> - <widget class="QLabel" name="label_5"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>Wallet</string> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="labelWalletStatus"> - <property name="toolTip"> - <string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</string> - </property> - <property name="styleSheet"> - <string notr="true">QLabel { color: red; }</string> - </property> - <property name="text"> - <string notr="true">(out of sync)</string> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> - </property> - </widget> - </item> - </layout> + <widget class="QLabel" name="label_5"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="text"> + <string>Balances</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="labelWalletStatus"> + <property name="cursor"> + <cursorShape>WhatsThisCursor</cursorShape> + </property> + <property name="toolTip"> + <string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</string> + </property> + <property name="styleSheet"> + <string notr="true">QLabel { color: red; }</string> + </property> + <property name="text"> + <string notr="true">(out of sync)</string> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> + </property> + </widget> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_8"> - <item> - <widget class="QLabel" name="labelWatchonly"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="text"> - <string>Watch-only:</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeType"> - <enum>QSizePolicy::Preferred</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> + <spacer name="horizontalSpacer_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> </item> </layout> </item> <item> - <layout class="QHBoxLayout" name="horizontalLayout_3"> - <item> - <layout class="QFormLayout" name="formLayout_2"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <property name="horizontalSpacing"> - <number>12</number> - </property> - <property name="verticalSpacing"> - <number>12</number> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Available:</string> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="labelBalance"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Your current spendable balance</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Pending:</string> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="labelUnconfirmed"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="labelImmatureText"> - <property name="text"> - <string>Immature:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="labelImmature"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Mined balance that has not yet matured</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="4" column="0"> - <widget class="QLabel" name="labelTotalText"> - <property name="text"> - <string>Total:</string> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QLabel" name="labelTotal"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Your current total balance</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - </layout> + <layout class="QGridLayout" name="gridLayout"> + <property name="spacing"> + <number>12</number> + </property> + <item row="2" column="2"> + <widget class="QLabel" name="labelWatchPending"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Unconfirmed transactions to watch-only addresses</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> </item> - <item> - <layout class="QFormLayout" name="formLayout"> - <property name="fieldGrowthPolicy"> - <enum>QFormLayout::AllNonFixedFieldsGrow</enum> - </property> - <property name="horizontalSpacing"> - <number>12</number> - </property> - <property name="verticalSpacing"> - <number>12</number> - </property> - <item row="0" column="1"> - <widget class="QLabel" name="labelWatchAvailable"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Your current balance in watch-only addresses</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="labelWatchPending"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Unconfirmed transactions to watch-only addresses</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="labelWatchImmature"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Mined balance in watch-only addresses that has not yet matured</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="3" column="0" colspan="2"> - <widget class="Line" name="lineWatchBalance"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>140</width> - <height>0</height> - </size> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="4" column="1"> - <widget class="QLabel" name="labelWatchTotal"> - <property name="font"> - <font> - <weight>75</weight> - <bold>true</bold> - </font> - </property> - <property name="cursor"> - <cursorShape>IBeamCursor</cursorShape> - </property> - <property name="toolTip"> - <string>Current total balance in watch-only addresses</string> - </property> - <property name="text"> - <string notr="true">0 BTC</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - </layout> + <item row="2" column="1"> + <widget class="QLabel" name="labelUnconfirmed"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> </item> - <item> - <spacer name="horizontalSpacer_3"> + <item row="3" column="2"> + <widget class="QLabel" name="labelWatchImmature"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Mined balance in watch-only addresses that has not yet matured</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="4" column="2"> + <widget class="Line" name="lineWatchBalance"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>140</width> + <height>0</height> + </size> + </property> <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="sizeType"> - <enum>QSizePolicy::Expanding</enum> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="labelTotalText"> + <property name="text"> + <string>Total:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="labelImmature"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Mined balance that has not yet matured</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="2" column="3"> + <spacer name="horizontalSpacer_2"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> <property name="sizeHint" stdset="0"> <size> - <width>20</width> + <width>40</width> <height>20</height> </size> </property> </spacer> </item> + <item row="3" column="0"> + <widget class="QLabel" name="labelImmatureText"> + <property name="text"> + <string>Immature:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="labelTotal"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Your current total balance</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="5" column="2"> + <widget class="QLabel" name="labelWatchTotal"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Current total balance in watch-only addresses</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="0" column="2"> + <widget class="QLabel" name="labelWatchonly"> + <property name="text"> + <string>Watch-only:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="labelBalanceText"> + <property name="text"> + <string>Available:</string> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="labelBalance"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Your current spendable balance</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="1" column="2"> + <widget class="QLabel" name="labelWatchAvailable"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="toolTip"> + <string>Your current balance in watch-only addresses</string> + </property> + <property name="text"> + <string notr="true">0.000 000 00 BTC</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="labelPendingText"> + <property name="text"> + <string>Pending:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="labelSpendable"> + <property name="text"> + <string>Spendable:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> </layout> </item> </layout> @@ -449,13 +419,22 @@ <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> <widget class="QLabel" name="label_4"> + <property name="font"> + <font> + <weight>75</weight> + <bold>true</bold> + </font> + </property> <property name="text"> - <string><b>Recent transactions</b></string> + <string>Recent transactions</string> </property> </widget> </item> <item> <widget class="QLabel" name="labelTransactionsStatus"> + <property name="cursor"> + <cursorShape>WhatsThisCursor</cursorShape> + </property> <property name="toolTip"> <string>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</string> </property> diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp index ed83909608..389a08d9e8 100644 --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -63,6 +63,13 @@ static boost::filesystem::detail::utf8_codecvt_facet utf8; #endif +#if defined(Q_OS_MAC) +extern double NSAppKitVersionNumber; +#if !defined(NSAppKitVersionNumber10_9) +#define NSAppKitVersionNumber10_9 1265 +#endif +#endif + namespace GUIUtil { QString dateTimeStr(const QDateTime &date) @@ -117,6 +124,10 @@ bool parseBitcoinURI(const QUrl &uri, SendCoinsRecipient *out) SendCoinsRecipient rv; rv.address = uri.path(); + // Trim any following forward slash which may have been added by the OS + if (rv.address.endsWith("/")) { + rv.address.truncate(rv.address.length() - 1); + } rv.amount = 0; #if QT_VERSION < 0x050000 @@ -370,8 +381,29 @@ void openDebugLogfile() QDesktopServices::openUrl(QUrl::fromLocalFile(boostPathToQString(pathDebug))); } +void SubstituteFonts() +{ +#if defined(Q_OS_MAC) +// Background: +// OSX's default font changed in 10.9 and QT is unable to find it with its +// usual fallback methods when building against the 10.7 sdk or lower. +// The 10.8 SDK added a function to let it find the correct fallback font. +// If this fallback is not properly loaded, some characters may fail to +// render correctly. +// +// Solution: If building with the 10.7 SDK or lower and the user's platform +// is 10.9 or higher at runtime, substitute the correct font. This needs to +// happen before the QApplication is created. +#if defined(MAC_OS_X_VERSION_MAX_ALLOWED) && MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_8 + if (floor(NSAppKitVersionNumber) >= NSAppKitVersionNumber10_9) + QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande"); +#endif +#endif +} + ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent) : - QObject(parent), size_threshold(size_threshold) + QObject(parent), + size_threshold(size_threshold) { } diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index dd31d051ee..0ae5154d4b 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -102,6 +102,9 @@ namespace GUIUtil // Open debug.log void openDebugLogfile(); + // Replace invalid default fonts with known good ones + void SubstituteFonts(); + /** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text representation if needed. This assures that Qt can word-wrap long tooltip messages. Tooltips longer than the provided size threshold (in characters) are wrapped. diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 1c700b37ff..b5a3de48ca 100644 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -162,15 +162,16 @@ void OverviewPage::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 bool showWatchOnlyImmature = watchImmatureBalance != 0; bool showWatchOnly = (watchOnlyBalance != 0 || watchUnconfBalance != 0 || showWatchOnlyImmature); - // for symmetry reasons also show immature label when the watchonly one is shown + // for symmetry reasons also show immature label when the watch-only one is shown ui->labelImmature->setVisible(showImmature || showWatchOnlyImmature); ui->labelImmatureText->setVisible(showImmature || showWatchOnlyImmature); - ui->labelWatchonly->setVisible(showWatchOnly); // show Watchonly label - ui->lineWatchBalance->setVisible(showWatchOnly); // show watchonly balance separator line - ui->labelWatchAvailable->setVisible(showWatchOnly); // show watchonly available balance - ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watchonly immature balance - ui->labelWatchPending->setVisible(showWatchOnly); // show watchonly pending balance - ui->labelWatchTotal->setVisible(showWatchOnly); // show watchonly total balance + ui->labelSpendable->setVisible(showWatchOnly); // show spendable label (only when watch-only is active) + ui->labelWatchonly->setVisible(showWatchOnly); // show watch-only label + ui->lineWatchBalance->setVisible(showWatchOnly); // show watch-only balance separator line + ui->labelWatchAvailable->setVisible(showWatchOnly); // show watch-only available balance + ui->labelWatchImmature->setVisible(showWatchOnlyImmature); // show watch-only immature balance + ui->labelWatchPending->setVisible(showWatchOnly); // show watch-only pending balance + ui->labelWatchTotal->setVisible(showWatchOnly); // show watch-only total balance } void OverviewPage::setClientModel(ClientModel *model) diff --git a/src/qt/peertablemodel.cpp b/src/qt/peertablemodel.cpp index 54b46867ea..cfa05300cf 100644 --- a/src/qt/peertablemodel.cpp +++ b/src/qt/peertablemodel.cpp @@ -75,8 +75,14 @@ public: } // Try to retrieve the CNodeStateStats for each node. - BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats) - stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats); + { + TRY_LOCK(cs_main, lockMain); + if (lockMain) + { + BOOST_FOREACH(CNodeCombinedStats &stats, cachedNodeStats) + stats.fNodeStateStatsAvailable = GetNodeStateStats(stats.nodeStats.nodeid, stats.nodeStateStats); + } + } if (sortColumn >= 0) // sort cacheNodeStats (use stable sort to prevent rows jumping around unneceesarily) diff --git a/src/qt/res/icons/toolbar.png b/src/qt/res/icons/toolbar.png Binary files differdeleted file mode 100644 index c82d96519c..0000000000 --- a/src/qt/res/icons/toolbar.png +++ /dev/null diff --git a/src/qt/res/icons/toolbar_testnet.png b/src/qt/res/icons/toolbar_testnet.png Binary files differdeleted file mode 100644 index 5995bc0667..0000000000 --- a/src/qt/res/icons/toolbar_testnet.png +++ /dev/null diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index 1e5198b85c..e511fe4222 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -531,3 +531,27 @@ Value getchaintips(const Array& params, bool fHelp) return res; } + +Value getmempoolinfo(const Array& params, bool fHelp) +{ + if (fHelp || params.size() != 0) + throw runtime_error( + "getmempoolinfo\n" + "\nReturns details on the active state of the TX memory pool.\n" + "\nResult:\n" + "{\n" + " \"size\": xxxxx (numeric) Current tx count\n" + " \"bytes\": xxxxx (numeric) Sum of all tx sizes\n" + "}\n" + "\nExamples:\n" + + HelpExampleCli("getmempoolinfo", "") + + HelpExampleRpc("getmempoolinfo", "") + ); + + Object ret; + ret.push_back(Pair("size", (int64_t) mempool.size())); + ret.push_back(Pair("bytes", (int64_t) mempool.GetTotalTxSize())); + + return ret; +} + diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index e7ed73310c..3b51c91e7c 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -135,11 +135,18 @@ vector<unsigned char> ParseHexO(const Object& o, string strKey) string CRPCTable::help(string strCommand) const { string strRet; + string category; set<rpcfn_type> setDone; + vector<pair<string, const CRPCCommand*> > vCommands; + for (map<string, const CRPCCommand*>::const_iterator mi = mapCommands.begin(); mi != mapCommands.end(); ++mi) + vCommands.push_back(make_pair(mi->second->category + mi->first, mi->second)); + sort(vCommands.begin(), vCommands.end()); + + BOOST_FOREACH(const PAIRTYPE(string, const CRPCCommand*)& command, vCommands) { - const CRPCCommand *pcmd = mi->second; - string strMethod = mi->first; + const CRPCCommand *pcmd = command.second; + string strMethod = pcmd->name; // We already filter duplicates, but these deprecated screw up the sort order if (strMethod.find("label") != string::npos) continue; @@ -162,8 +169,20 @@ string CRPCTable::help(string strCommand) const // Help text is returned in an exception string strHelp = string(e.what()); if (strCommand == "") + { if (strHelp.find('\n') != string::npos) strHelp = strHelp.substr(0, strHelp.find('\n')); + + if (category != pcmd->category) + { + if (!category.empty()) + strRet += "\n"; + category = pcmd->category; + string firstLetter = category.substr(0,1); + boost::to_upper(firstLetter); + strRet += "== " + firstLetter + category.substr(1) + " ==\n"; + } + } strRet += strHelp + "\n"; } } @@ -213,103 +232,106 @@ Value stop(const Array& params, bool fHelp) static const CRPCCommand vRPCCommands[] = -{ // name actor (function) okSafeMode threadSafe reqWallet - // ------------------------ ----------------------- ---------- ---------- --------- +{ // category name actor (function) okSafeMode threadSafe reqWallet + // --------------------- ------------------------ ----------------------- ---------- ---------- --------- /* Overall control/query calls */ - { "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */ - { "help", &help, true, true, false }, - { "stop", &stop, true, true, false }, + { "control", "getinfo", &getinfo, true, false, false }, /* uses wallet if enabled */ + { "control", "help", &help, true, true, false }, + { "control", "stop", &stop, true, true, false }, /* P2P networking */ - { "getnetworkinfo", &getnetworkinfo, true, false, false }, - { "addnode", &addnode, true, true, false }, - { "getaddednodeinfo", &getaddednodeinfo, true, true, false }, - { "getconnectioncount", &getconnectioncount, true, false, false }, - { "getnettotals", &getnettotals, true, true, false }, - { "getpeerinfo", &getpeerinfo, true, false, false }, - { "ping", &ping, true, false, false }, + { "network", "getnetworkinfo", &getnetworkinfo, true, false, false }, + { "network", "addnode", &addnode, true, true, false }, + { "network", "getaddednodeinfo", &getaddednodeinfo, true, true, false }, + { "network", "getconnectioncount", &getconnectioncount, true, false, false }, + { "network", "getnettotals", &getnettotals, true, true, false }, + { "network", "getpeerinfo", &getpeerinfo, true, false, false }, + { "network", "ping", &ping, true, false, false }, /* Block chain and UTXO */ - { "getblockchaininfo", &getblockchaininfo, true, false, false }, - { "getbestblockhash", &getbestblockhash, true, false, false }, - { "getblockcount", &getblockcount, true, false, false }, - { "getblock", &getblock, true, false, false }, - { "getblockhash", &getblockhash, true, false, false }, - { "getchaintips", &getchaintips, true, false, false }, - { "getdifficulty", &getdifficulty, true, false, false }, - { "getrawmempool", &getrawmempool, true, false, false }, - { "gettxout", &gettxout, true, false, false }, - { "gettxoutsetinfo", &gettxoutsetinfo, true, false, false }, - { "verifychain", &verifychain, true, false, false }, + { "blockchain", "getblockchaininfo", &getblockchaininfo, true, false, false }, + { "blockchain", "getbestblockhash", &getbestblockhash, true, false, false }, + { "blockchain", "getblockcount", &getblockcount, true, false, false }, + { "blockchain", "getblock", &getblock, true, false, false }, + { "blockchain", "getblockhash", &getblockhash, true, false, false }, + { "blockchain", "getchaintips", &getchaintips, true, false, false }, + { "blockchain", "getdifficulty", &getdifficulty, true, false, false }, + { "blockchain", "getmempoolinfo", &getmempoolinfo, true, true, false }, + { "blockchain", "getrawmempool", &getrawmempool, true, false, false }, + { "blockchain", "gettxout", &gettxout, true, false, false }, + { "blockchain", "gettxoutsetinfo", &gettxoutsetinfo, true, false, false }, + { "blockchain", "verifychain", &verifychain, true, false, false }, /* Mining */ - { "getblocktemplate", &getblocktemplate, true, false, false }, - { "getmininginfo", &getmininginfo, true, false, false }, - { "getnetworkhashps", &getnetworkhashps, true, false, false }, - { "prioritisetransaction", &prioritisetransaction, true, false, false }, - { "submitblock", &submitblock, true, true, false }, + { "mining", "getblocktemplate", &getblocktemplate, true, false, false }, + { "mining", "getmininginfo", &getmininginfo, true, false, false }, + { "mining", "getnetworkhashps", &getnetworkhashps, true, false, false }, + { "mining", "prioritisetransaction", &prioritisetransaction, true, false, false }, + { "mining", "submitblock", &submitblock, true, true, false }, + +#ifdef ENABLE_WALLET + /* Coin generation */ + { "generating", "getgenerate", &getgenerate, true, false, false }, + { "generating", "gethashespersec", &gethashespersec, true, false, false }, + { "generating", "setgenerate", &setgenerate, true, true, false }, +#endif /* Raw transactions */ - { "createrawtransaction", &createrawtransaction, true, false, false }, - { "decoderawtransaction", &decoderawtransaction, true, false, false }, - { "decodescript", &decodescript, true, false, false }, - { "getrawtransaction", &getrawtransaction, true, false, false }, - { "sendrawtransaction", &sendrawtransaction, false, false, false }, - { "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */ + { "rawtransactions", "createrawtransaction", &createrawtransaction, true, false, false }, + { "rawtransactions", "decoderawtransaction", &decoderawtransaction, true, false, false }, + { "rawtransactions", "decodescript", &decodescript, true, false, false }, + { "rawtransactions", "getrawtransaction", &getrawtransaction, true, false, false }, + { "rawtransactions", "sendrawtransaction", &sendrawtransaction, false, false, false }, + { "rawtransactions", "signrawtransaction", &signrawtransaction, false, false, false }, /* uses wallet if enabled */ /* Utility functions */ - { "createmultisig", &createmultisig, true, true , false }, - { "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */ - { "verifymessage", &verifymessage, true, false, false }, - { "estimatefee", &estimatefee, true, true, false }, - { "estimatepriority", &estimatepriority, true, true, false }, + { "util", "createmultisig", &createmultisig, true, true , false }, + { "util", "validateaddress", &validateaddress, true, false, false }, /* uses wallet if enabled */ + { "util", "verifymessage", &verifymessage, true, false, false }, + { "util", "estimatefee", &estimatefee, true, true, false }, + { "util", "estimatepriority", &estimatepriority, true, true, false }, #ifdef ENABLE_WALLET /* Wallet */ - { "addmultisigaddress", &addmultisigaddress, true, false, true }, - { "backupwallet", &backupwallet, true, false, true }, - { "dumpprivkey", &dumpprivkey, true, false, true }, - { "dumpwallet", &dumpwallet, true, false, true }, - { "encryptwallet", &encryptwallet, true, false, true }, - { "getaccountaddress", &getaccountaddress, true, false, true }, - { "getaccount", &getaccount, true, false, true }, - { "getaddressesbyaccount", &getaddressesbyaccount, true, false, true }, - { "getbalance", &getbalance, false, false, true }, - { "getnewaddress", &getnewaddress, true, false, true }, - { "getrawchangeaddress", &getrawchangeaddress, true, false, true }, - { "getreceivedbyaccount", &getreceivedbyaccount, false, false, true }, - { "getreceivedbyaddress", &getreceivedbyaddress, false, false, true }, - { "gettransaction", &gettransaction, false, false, true }, - { "getunconfirmedbalance", &getunconfirmedbalance, false, false, true }, - { "getwalletinfo", &getwalletinfo, false, false, true }, - { "importprivkey", &importprivkey, true, false, true }, - { "importwallet", &importwallet, true, false, true }, - { "importaddress", &importaddress, true, false, true }, - { "keypoolrefill", &keypoolrefill, true, false, true }, - { "listaccounts", &listaccounts, false, false, true }, - { "listaddressgroupings", &listaddressgroupings, false, false, true }, - { "listlockunspent", &listlockunspent, false, false, true }, - { "listreceivedbyaccount", &listreceivedbyaccount, false, false, true }, - { "listreceivedbyaddress", &listreceivedbyaddress, false, false, true }, - { "listsinceblock", &listsinceblock, false, false, true }, - { "listtransactions", &listtransactions, false, false, true }, - { "listunspent", &listunspent, false, false, true }, - { "lockunspent", &lockunspent, true, false, true }, - { "move", &movecmd, false, false, true }, - { "sendfrom", &sendfrom, false, false, true }, - { "sendmany", &sendmany, false, false, true }, - { "sendtoaddress", &sendtoaddress, false, false, true }, - { "setaccount", &setaccount, true, false, true }, - { "settxfee", &settxfee, true, false, true }, - { "signmessage", &signmessage, true, false, true }, - { "walletlock", &walletlock, true, false, true }, - { "walletpassphrasechange", &walletpassphrasechange, true, false, true }, - { "walletpassphrase", &walletpassphrase, true, false, true }, - - /* Wallet-enabled mining */ - { "getgenerate", &getgenerate, true, false, false }, - { "gethashespersec", &gethashespersec, true, false, false }, - { "setgenerate", &setgenerate, true, true, false }, + { "wallet", "addmultisigaddress", &addmultisigaddress, true, false, true }, + { "wallet", "backupwallet", &backupwallet, true, false, true }, + { "wallet", "dumpprivkey", &dumpprivkey, true, false, true }, + { "wallet", "dumpwallet", &dumpwallet, true, false, true }, + { "wallet", "encryptwallet", &encryptwallet, true, false, true }, + { "wallet", "getaccountaddress", &getaccountaddress, true, false, true }, + { "wallet", "getaccount", &getaccount, true, false, true }, + { "wallet", "getaddressesbyaccount", &getaddressesbyaccount, true, false, true }, + { "wallet", "getbalance", &getbalance, false, false, true }, + { "wallet", "getnewaddress", &getnewaddress, true, false, true }, + { "wallet", "getrawchangeaddress", &getrawchangeaddress, true, false, true }, + { "wallet", "getreceivedbyaccount", &getreceivedbyaccount, false, false, true }, + { "wallet", "getreceivedbyaddress", &getreceivedbyaddress, false, false, true }, + { "wallet", "gettransaction", &gettransaction, false, false, true }, + { "wallet", "getunconfirmedbalance", &getunconfirmedbalance, false, false, true }, + { "wallet", "getwalletinfo", &getwalletinfo, false, false, true }, + { "wallet", "importprivkey", &importprivkey, true, false, true }, + { "wallet", "importwallet", &importwallet, true, false, true }, + { "wallet", "importaddress", &importaddress, true, false, true }, + { "wallet", "keypoolrefill", &keypoolrefill, true, false, true }, + { "wallet", "listaccounts", &listaccounts, false, false, true }, + { "wallet", "listaddressgroupings", &listaddressgroupings, false, false, true }, + { "wallet", "listlockunspent", &listlockunspent, false, false, true }, + { "wallet", "listreceivedbyaccount", &listreceivedbyaccount, false, false, true }, + { "wallet", "listreceivedbyaddress", &listreceivedbyaddress, false, false, true }, + { "wallet", "listsinceblock", &listsinceblock, false, false, true }, + { "wallet", "listtransactions", &listtransactions, false, false, true }, + { "wallet", "listunspent", &listunspent, false, false, true }, + { "wallet", "lockunspent", &lockunspent, true, false, true }, + { "wallet", "move", &movecmd, false, false, true }, + { "wallet", "sendfrom", &sendfrom, false, false, true }, + { "wallet", "sendmany", &sendmany, false, false, true }, + { "wallet", "sendtoaddress", &sendtoaddress, false, false, true }, + { "wallet", "setaccount", &setaccount, true, false, true }, + { "wallet", "settxfee", &settxfee, true, false, true }, + { "wallet", "signmessage", &signmessage, true, false, true }, + { "wallet", "walletlock", &walletlock, true, false, true }, + { "wallet", "walletpassphrasechange", &walletpassphrasechange, true, false, true }, + { "wallet", "walletpassphrase", &walletpassphrase, true, false, true }, #endif // ENABLE_WALLET }; diff --git a/src/rpcserver.h b/src/rpcserver.h index 176852ca8f..b850d15d4e 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -71,6 +71,7 @@ typedef json_spirit::Value(*rpcfn_type)(const json_spirit::Array& params, bool f class CRPCCommand { public: + std::string category; std::string name; rpcfn_type actor; bool okSafeMode; @@ -199,6 +200,7 @@ extern json_spirit::Value getblockcount(const json_spirit::Array& params, bool f extern json_spirit::Value getbestblockhash(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getdifficulty(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value settxfee(const json_spirit::Array& params, bool fHelp); +extern json_spirit::Value getmempoolinfo(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getrawmempool(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblockhash(const json_spirit::Array& params, bool fHelp); extern json_spirit::Value getblock(const json_spirit::Array& params, bool fHelp); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 667ca33ce1..215da2ea12 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1518,7 +1518,7 @@ Value gettransaction(const Array& params, bool fHelp) " \"hex\" : \"data\" (string) Raw data for transaction\n" "}\n" - "\nbExamples\n" + "\nExamples:\n" + HelpExampleCli("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") + HelpExampleRpc("gettransaction", "\"1075db55d416d3ca199f55b6084e2115b9345e16c5cf302fc80e9d5fbf5d48d\"") ); diff --git a/src/script.cpp b/src/script.cpp index 39ae001db8..942e8810db 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -1444,18 +1444,6 @@ unsigned int HaveKeys(const vector<valtype>& pubkeys, const CKeyStore& keystore) return nResult; } - -class CKeyStoreIsMineVisitor : public boost::static_visitor<bool> -{ -private: - const CKeyStore *keystore; -public: - CKeyStoreIsMineVisitor(const CKeyStore *keystoreIn) : keystore(keystoreIn) { } - bool operator()(const CNoDestination &dest) const { return false; } - bool operator()(const CKeyID &keyID) const { return keystore->HaveKey(keyID); } - bool operator()(const CScriptID &scriptID) const { return keystore->HaveCScript(scriptID); } -}; - isminetype IsMine(const CKeyStore &keystore, const CTxDestination& dest) { CScript script; diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 29924fff09..80cae68244 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -402,6 +402,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry) for (unsigned int i = 0; i < tx.vin.size(); i++) mapNextTx[tx.vin[i].prevout] = CInPoint(&tx, i); nTransactionsUpdated++; + totalTxSize += entry.GetTxSize(); } return true; } @@ -426,6 +427,8 @@ void CTxMemPool::remove(const CTransaction &tx, std::list<CTransaction>& removed removed.push_front(tx); BOOST_FOREACH(const CTxIn& txin, tx.vin) mapNextTx.erase(txin.prevout); + + totalTxSize -= mapTx[hash].GetTxSize(); mapTx.erase(hash); nTransactionsUpdated++; } @@ -477,6 +480,7 @@ void CTxMemPool::clear() LOCK(cs); mapTx.clear(); mapNextTx.clear(); + totalTxSize = 0; ++nTransactionsUpdated; } @@ -487,9 +491,12 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const LogPrint("mempool", "Checking mempool with %u transactions and %u inputs\n", (unsigned int)mapTx.size(), (unsigned int)mapNextTx.size()); + uint64_t checkTotal = 0; + LOCK(cs); for (std::map<uint256, CTxMemPoolEntry>::const_iterator it = mapTx.begin(); it != mapTx.end(); it++) { unsigned int i = 0; + checkTotal += it->second.GetTxSize(); const CTransaction& tx = it->second.GetTx(); BOOST_FOREACH(const CTxIn &txin, tx.vin) { // Check that every mempool transaction's inputs refer to available coins, or other mempool tx's. @@ -518,6 +525,8 @@ void CTxMemPool::check(CCoinsViewCache *pcoins) const assert(tx.vin.size() > it->second.n); assert(it->first == it->second.ptx->vin[it->second.n].prevout); } + + assert(totalTxSize == checkTotal); } void CTxMemPool::queryHashes(vector<uint256>& vtxid) diff --git a/src/txmempool.h b/src/txmempool.h index 41b2c52f39..2577397bce 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -68,6 +68,7 @@ private: CMinerPolicyEstimator* minerPolicyEstimator; CFeeRate minRelayFee; // Passed to constructor to avoid dependency on main + uint64_t totalTxSize; // sum of all mempool tx' byte sizes public: mutable CCriticalSection cs; @@ -108,6 +109,11 @@ public: LOCK(cs); return mapTx.size(); } + uint64_t GetTotalTxSize() + { + LOCK(cs); + return totalTxSize; + } bool exists(uint256 hash) { diff --git a/src/util.cpp b/src/util.cpp index d3fa5182f3..ae2145a3a0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -3,6 +3,10 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#if defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" +#endif + #include "util.h" #include "chainparamsbase.h" @@ -17,16 +21,15 @@ #ifndef WIN32 // for posix_fallocate -#ifdef __linux_ +#ifdef __linux__ #ifdef _POSIX_C_SOURCE #undef _POSIX_C_SOURCE #endif #define _POSIX_C_SOURCE 200112L -#include <sys/prctl.h> -#endif +#endif // __linux__ #include <algorithm> #include <fcntl.h> @@ -61,6 +64,10 @@ #include <shlobj.h> #endif +#ifdef HAVE_SYS_PRCTL_H +#include <sys/prctl.h> +#endif + #include <boost/algorithm/string/case_conv.hpp> // for to_lower() #include <boost/algorithm/string/join.hpp> #include <boost/algorithm/string/predicate.hpp> // for startswith() and endswith() |