Mercurial > hg > bitcoin
changeset 3449:9b67399e93a3 draft
Merge pull request #1728 from xanatos/patch-11
Removed duplicated lock
author | Wladimir J. van der Laan <laanwj@gmail.com> |
---|---|
date | Mon, 03 Sep 2012 08:00:18 -0700 |
parents | 2ae05b270672 (diff) 3bb9018628ee (current diff) |
children | 83b24f40896f |
files | |
diffstat | 27 files changed, 408 insertions(+), 244 deletions(-) [+] |
line wrap: on
line diff
--- a/bitcoin-qt.pro +++ b/bitcoin-qt.pro @@ -1,6 +1,6 @@ TEMPLATE = app TARGET = bitcoin-qt -VERSION = 0.6.99 +VERSION = 0.7.0 INCLUDEPATH += src src/json src/qt DEFINES += QT_GUI BOOST_THREAD_USE_LIB BOOST_SPIRIT_THREADSAFE CONFIG += no_include_pwd @@ -75,12 +75,12 @@ # or: qmake "USE_IPV6=0" (disabled by default) # or: qmake "USE_IPV6=-" (not supported) contains(USE_IPV6, -) { - message(Building without IPv6 support) + message(Building without IPv6 support) } else { - count(USE_IPV6, 0) { - USE_IPV6=1 - } - DEFINES += USE_IPV6=$$USE_IPV6 + count(USE_IPV6, 0) { + USE_IPV6=1 + } + DEFINES += USE_IPV6=$$USE_IPV6 } contains(BITCOIN_NEED_QT_PLUGINS, 1) { @@ -92,7 +92,7 @@ # for extra security against potential buffer overflows QMAKE_CXXFLAGS += -fstack-protector QMAKE_LFLAGS += -fstack-protector - # do not enable this on windows, as it will result in a non-working executable! + # do not enable this on windows cross compile with mingw 4.2.x, as it will result in a non-working executable! } # regenerate src/build.h @@ -176,7 +176,8 @@ src/allocators.h \ src/ui_interface.h \ src/qt/rpcconsole.h \ - src/version.h + src/version.h \ + src/netbase.h SOURCES += src/qt/bitcoin.cpp src/qt/bitcoingui.cpp \ src/qt/transactiontablemodel.cpp \ @@ -202,9 +203,6 @@ src/addrman.cpp \ src/db.cpp \ src/walletdb.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 \ @@ -298,7 +296,7 @@ # platform specific defaults, if not overridden on command line isEmpty(BOOST_LIB_SUFFIX) { macx:BOOST_LIB_SUFFIX = -mt - windows:BOOST_LIB_SUFFIX = -mgw44-mt-s-1_49 + windows:BOOST_LIB_SUFFIX = -mgw44-mt-s-1_50 } isEmpty(BOOST_THREAD_LIB_SUFFIX) { @@ -359,6 +357,7 @@ # -lgdi32 has to happen after -lcrypto (see #681) windows:LIBS += -lole32 -luuid -lgdi32 LIBS += -lboost_system$$BOOST_LIB_SUFFIX -lboost_filesystem$$BOOST_LIB_SUFFIX -lboost_program_options$$BOOST_LIB_SUFFIX -lboost_thread$$BOOST_THREAD_LIB_SUFFIX +windows:LIBS += -lboost_chrono$$BOOST_LIB_SUFFIX contains(RELEASE, 1) { !windows:!macx {
--- a/contrib/gitian-descriptors/boost-win32.yml +++ b/contrib/gitian-descriptors/boost-win32.yml @@ -11,28 +11,12 @@ reference_datetime: "2011-01-30 00:00:00" remotes: [] files: -- "boost_1_49_0.tar.bz2" +- "boost_1_50_0.tar.bz2" script: | TMPDIR="$HOME/tmpdir" mkdir -p $TMPDIR/bin/$GBUILD_BITS $TMPDIR/include - tar xjf boost_1_49_0.tar.bz2 - cd boost_1_49_0 - echo "--- tmp_dir_helpers.orig.hpp 2012-06-10 01:39:25.403268210 +0200 -+++ tmp_dir_helpers.hpp 2012-06-10 01:41:14.653823479 +0200 -@@ -19,9 +19,9 @@ - #include <string> - - #if defined(BOOST_INTERPROCESS_WINDOWS) -- //#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME -- //#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME -- //#include <boost/interprocess/detail/win32_api.hpp> -+ #define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME -+ #define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME -+ #include <boost/interprocess/detail/win32_api.hpp> - #elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__APPLE__) - //#include <sys/sysctl.h> - //#if defined(CTL_KERN) && defined (KERN_BOOTTIME)" > useboottime.patch - patch boost/interprocess/detail/tmp_dir_helpers.hpp useboottime.patch + tar xjf boost_1_50_0.tar.bz2 + cd boost_1_50_0 echo "using gcc : 4.4 : i586-mingw32msvc-g++ : <rc>i586-mingw32msvc-windres @@ -50,5 +34,5 @@ cd $TMPDIR export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 export FAKETIME=$REFERENCE_DATETIME - zip -r boost-win32-1.49.0-gitian2.zip * - cp boost-win32-1.49.0-gitian2.zip $OUTDIR + zip -r boost-win32-1.50.0-gitian2.zip * + cp boost-win32-1.50.0-gitian2.zip $OUTDIR
--- a/contrib/gitian-descriptors/gitian-win32.yml +++ b/contrib/gitian-descriptors/gitian-win32.yml @@ -16,7 +16,7 @@ "dir": "bitcoin" files: - "qt-win32-4.7.4-gitian.zip" -- "boost-win32-1.49.0-gitian2.zip" +- "boost-win32-1.50.0-gitian2.zip" - "bitcoin-deps-0.0.4.zip" script: | # @@ -26,10 +26,10 @@ cd $HOME/build/ export PATH=$PATH:$HOME/qt/bin/ # - mkdir boost_1_49_0 - cd boost_1_49_0 + mkdir boost_1_50_0 + cd boost_1_50_0 mkdir -p stage/lib - unzip ../boost-win32-1.49.0-gitian2.zip + unzip ../boost-win32-1.50.0-gitian2.zip cd bin/$GBUILD_BITS for lib in *; do i586-mingw32msvc-ar rc ../../stage/lib/libboost_${lib}-mt-s.a $lib/*.o @@ -51,7 +51,7 @@ export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 export FAKETIME=$REFERENCE_DATETIME export TZ=UTC - $HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_47_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_47_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.1b OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.1b/include QRENCODE_LIB_PATH=$HOME/build/qrencode-3.2.0/.libs QRENCODE_INCLUDE_PATH=$HOME/build/qrencode-3.2.0 USE_QRCODE=1 INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin USE_BUILD_INFO=1 + $HOME/qt/src/bin/qmake -spec unsupported/win32-g++-cross MINIUPNPC_LIB_PATH=$HOME/build/miniupnpc MINIUPNPC_INCLUDE_PATH=$HOME/build/ BDB_LIB_PATH=$HOME/build/db-4.8.30.NC/build_unix BDB_INCLUDE_PATH=$HOME/build/db-4.8.30.NC/build_unix BOOST_LIB_PATH=$HOME/build/boost_1_50_0/stage/lib BOOST_INCLUDE_PATH=$HOME/build/boost_1_50_0 BOOST_LIB_SUFFIX=-mt-s BOOST_THREAD_LIB_SUFFIX=_win32-mt-s OPENSSL_LIB_PATH=$HOME/build/openssl-1.0.1b OPENSSL_INCLUDE_PATH=$HOME/build/openssl-1.0.1b/include QRENCODE_LIB_PATH=$HOME/build/qrencode-3.2.0/.libs QRENCODE_INCLUDE_PATH=$HOME/build/qrencode-3.2.0 USE_QRCODE=1 INCLUDEPATH=$HOME/build DEFINES=BOOST_THREAD_USE_LIB BITCOIN_NEED_QT_PLUGINS=1 QMAKE_LRELEASE=lrelease QMAKE_CXXFLAGS=-frandom-seed=bitcoin QMAKE_LFLAGS=-frandom-seed=bitcoin USE_BUILD_INFO=1 make $MAKEOPTS cp release/bitcoin-qt.exe $OUTDIR/ #
--- a/doc/README +++ b/doc/README @@ -1,4 +1,4 @@ -Bitcoin 0.6.99 BETA +Bitcoin 0.7.0 BETA Copyright (c) 2009-2012 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying
--- a/doc/README_windows.txt +++ b/doc/README_windows.txt @@ -1,4 +1,4 @@ -Bitcoin 0.6.99 BETA +Bitcoin 0.7.0 BETA Copyright (c) 2009-2012 Bitcoin Developers Distributed under the MIT/X11 software license, see the accompanying
--- a/doc/release-notes.txt +++ b/doc/release-notes.txt @@ -8,14 +8,23 @@ +Bitcoin Improvement Proposals implemented +----------------------------------------- +BIP 22 - 'getblocktemplate', 'submitblock' RPCs +BIP 34 - block version 2, height in coinbase +BIP 35 - 'mempool' message, extended 'getdata' message behavior + + Core bitcoin handling and blockchain database --------------------------------------------- * Reduced CPU usage, by eliminating some redundant hash calculations * Cache signature verifications, to eliminate redundant signature checks +* Transactions with zero-value outputs are considered non-standard * Mining: when creating new blocks, sort 'paid' area by fee-per-kb * Database: better validation of on-disk stored data * Database: minor optimizations and reliability improvements * -loadblock=FILE will import an external block file +* Additional DoS prevention measures JSON-RPC API @@ -30,31 +39,52 @@ * Added raw transaction API. See https://gist.github.com/2839617 * Added 'getrawmempool', to list contents of TX memory pool * Added 'getpeerinfo', to list data about each connected network peer +* Added 'listaddressgroupings' for better coin control * Rework gettransaction, getblock calls. 'gettransaction' responds for non-wallet TXs now. * Remove deprecated RPC 'getblocknumber' +* Remove superceded RPC 'getmemorypool' (see BIP 22, above) +* New blockchain checkpoint at block 193,000 +* listtransactions output now displays "smart" times for transactions, + and 'blocktime' and 'timereceived' fields were added P2P networking -------------- * IPv6 support -* Tor/I2P hidden service support +* Tor hidden service support * Attempts to fix "stuck blockchain download" problems * Replace BDB database "addr.dat" with internally-managed "peers.dat" file containing peer address data. * Lower default send buffer from 10MB to 1MB * proxy: SOCKS5 by default -* Support connecting by hostnames passed to proxy (-proxydns) -* Add -seednode connections, and use this for -dnsseed + -proxydns +* Support connecting by hostnames passed to proxy +* Add -seednode connections, and use this instead of DNS seeds when proxied * Added -externalip and -discover -* Add -onlynet to prevent connections to a given network +* Add -onlynet to connect only to a given network (IPv4, IPv6, or Tor) * Separate listening sockets, -bind=<addr> Qt GUI ---------------------- -????? - +------ +* Add UI RPC console / debug window +* Re-Enable URI handling on Windows, add safety checks and tray-notifications +* Harmonize the use of ellipsis ("...") to be used in menus, but not on buttons +* Add 2 labels to the overviewpage that display Wallet and Transaction status (obsolete or current) +* Extend the optionsdialog (e.g. language selection) and re-work it to a tabbed UI +* Merge sign/verify message into a single window with tabbed UI +* Ensure a changed bitcoin unit immediately updates all GUI elements that use units +* Update QR Code dialog +* Improve error reporting at startup +* Fine-grained UI updates for a much smoother UI during block downloads +* Remove autocorrection of 0/i in addresses in UI +* Reorganize tray icon menu into more logical order +* Persistently poll for balance change when number of blocks changed +* Much better translations +* Override progress bar design on platforms with segmented progress bars to assist with readability +* Added 'immature balance' display on the overview page +* (Windows only): enable ASLR and DEP for bitcoin-qt.exe +* (Windows only): add meta-data to bitcoin-qt.exe (e.g. description) Internal codebase ----------------- @@ -67,5 +97,3 @@ * Reopen debug.log upon SIGHUP * Bash programmable completion for bitcoind(1) * On supported OS's, each thread is given a useful name - -
--- a/share/setup.nsi +++ b/share/setup.nsi @@ -5,7 +5,7 @@ # General Symbol Definitions !define REGKEY "SOFTWARE\$(^Name)" -!define VERSION 0.6.99 +!define VERSION 0.7.0 !define COMPANY "Bitcoin project" !define URL http://www.bitcoin.org/ @@ -45,13 +45,13 @@ !insertmacro MUI_LANGUAGE English # Installer attributes -OutFile bitcoin-0.6.99-win32-setup.exe +OutFile bitcoin-0.7.0-win32-setup.exe InstallDir $PROGRAMFILES\Bitcoin CRCCheck on XPStyle on BrandingText " " ShowInstDetails show -VIProductVersion 0.6.99.0 +VIProductVersion 0.7.0.0 VIAddVersionKey ProductName Bitcoin VIAddVersionKey ProductVersion "${VERSION}" VIAddVersionKey CompanyName "${COMPANY}"
--- a/src/init.cpp +++ b/src/init.cpp @@ -225,7 +225,7 @@ " -datadir=<dir> " + _("Specify data directory") + "\n" + " -dbcache=<n> " + _("Set database cache size in megabytes (default: 25)") + "\n" + " -dblogsize=<n> " + _("Set database disk log size in megabytes (default: 100)") + "\n" + - " -timeout=<n> " + _("Specify connection timeout (in milliseconds)") + "\n" + + " -timeout=<n> " + _("Specify connection timeout in milliseconds (default: 5000))") + "\n" + " -proxy=<ip:port> " + _("Connect through socks proxy") + "\n" + " -socks=<n> " + _("Select the version of socks proxy to use (4-5, default: 5)") + "\n" + " -tor=<ip:port> " + _("Use proxy to reach tor hidden services (default: same as -proxy)") + "\n"
--- a/src/irc.cpp +++ b/src/irc.cpp @@ -207,16 +207,22 @@ void ThreadIRCSeed2(void* parg) { - /* Don't advertise on IRC if we don't allow incoming connections */ - if (mapArgs.count("-connect") || fNoListen) + // Don't connect to IRC if we won't use IPv4 connections. + if (IsLimited(NET_IPV4)) return; + // ... or if we won't make outbound connections and won't accept inbound ones. + if (mapArgs.count("-connect") && fNoListen) + return; + + // ... or if IRC is not enabled. if (!GetBoolArg("-irc", false)) return; printf("ThreadIRCSeed started\n"); int nErrorWait = 10; int nRetryWait = 10; + int nNameRetry = 0; while (!fShutdown) { @@ -251,7 +257,9 @@ CNetAddr addrIPv4("1.2.3.4"); // arbitrary IPv4 address to make GetLocal prefer IPv4 addresses CService addrLocal; string strMyName; - if (GetLocal(addrLocal, &addrIPv4)) + // Don't use our IP as our nick if we're not listening + // or if it keeps failing because the nick is already in use. + if (!fNoListen && GetLocal(addrLocal, &addrIPv4) && nNameRetry<3) strMyName = EncodeAddress(GetLocalAddress(&addrConnect)); if (strMyName == "") strMyName = strprintf("x%u", GetRand(1000000000)); @@ -267,6 +275,7 @@ if (nRet == 2) { printf("IRC name already in use\n"); + nNameRetry++; Wait(10); continue; } @@ -276,6 +285,7 @@ else return; } + nNameRetry = 0; Sleep(500); // Get our external IP from the IRC server and re-nick before joining the channel @@ -283,7 +293,8 @@ if (GetIPFromIRC(hSocket, strMyName, addrFromIRC)) { printf("GetIPFromIRC() returned %s\n", addrFromIRC.ToString().c_str()); - if (addrFromIRC.IsRoutable()) + // Don't use our IP as our nick if we're not listening + if (!fNoListen && addrFromIRC.IsRoutable()) { // IRC lets you to re-nick AddLocal(addrFromIRC, LOCAL_IRC); @@ -291,7 +302,7 @@ Send(hSocket, strprintf("NICK %s\r", strMyName.c_str()).c_str()); } } - + if (fTestNet) { Send(hSocket, "JOIN #bitcoinTEST3\r"); Send(hSocket, "WHO #bitcoinTEST3\r");
--- a/src/main.cpp +++ b/src/main.cpp @@ -2322,6 +2322,28 @@ if (!IsInEffect()) return false; + // alert.nID=max is reserved for if the alert key is + // compromised. It must have a pre-defined message, + // must never expire, must apply to all versions, + // and must cancel all previous + // alerts or it will be ignored (so an attacker can't + // send an "everything is OK, don't panic" version that + // cannot be overridden): + int maxInt = std::numeric_limits<int>::max(); + if (nID == maxInt) + { + if (!( + nExpiration == maxInt && + nCancel == (maxInt-1) && + nMinVer == 0 && + nMaxVer == maxInt && + setSubVer.empty() && + nPriority == maxInt && + strStatusBar == "URGENT: Alert key compromised, upgrade required" + )) + return false; + } + { LOCK(cs_mapAlerts); // Cancel previous alerts @@ -2997,14 +3019,27 @@ CAlert alert; vRecv >> alert; - if (alert.ProcessAlert()) + uint256 alertHash = alert.GetHash(); + if (pfrom->setKnown.count(alertHash) == 0) { - // Relay - pfrom->setKnown.insert(alert.GetHash()); + if (alert.ProcessAlert()) { - LOCK(cs_vNodes); - BOOST_FOREACH(CNode* pnode, vNodes) - alert.RelayTo(pnode); + // Relay + pfrom->setKnown.insert(alertHash); + { + LOCK(cs_vNodes); + BOOST_FOREACH(CNode* pnode, vNodes) + alert.RelayTo(pnode); + } + } + else { + // Small DoS penalty so peers that send us lots of + // duplicate/expired/invalid-signature/whatever alerts + // eventually get banned. + // This isn't a Misbehaving(100) (immediate ban) because the + // peer might be an older or different implementation with + // a different signature key, etc. + pfrom->Misbehaving(10); } } }
--- a/src/main.h +++ b/src/main.h @@ -1535,7 +1535,7 @@ uint256 GetHash() const { - return SerializeHash(*this); + return Hash(this->vchMsg.begin(), this->vchMsg.end()); } bool IsInEffect() const
--- a/src/makefile.linux-mingw +++ b/src/makefile.linux-mingw @@ -10,13 +10,13 @@ INCLUDEPATHS= \ -I"$(CURDIR)" \ -I"$(CURDIR)"/obj \ - -I"$(DEPSDIR)/boost_1_49_0" \ + -I"$(DEPSDIR)/boost_1_50_0" \ -I"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ -I"$(DEPSDIR)/openssl-1.0.1b/include" \ -I"$(DEPSDIR)" LIBPATHS= \ - -L"$(DEPSDIR)/boost_1_49_0/stage/lib" \ + -L"$(DEPSDIR)/boost_1_50_0/stage/lib" \ -L"$(DEPSDIR)/db-4.8.30.NC/build_unix" \ -L"$(DEPSDIR)/openssl-1.0.1b" @@ -25,6 +25,7 @@ -l boost_filesystem-mt-s \ -l boost_program_options-mt-s \ -l boost_thread_win32-mt-s \ + -l boost_chrono-mt-s \ -l db_cxx \ -l ssl \ -l crypto @@ -32,6 +33,7 @@ DEFS=-D_MT -DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE DEBUGFLAGS=-g CFLAGS=-O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) +LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) @@ -92,7 +94,7 @@ i586-mingw32msvc-g++ -c $(CFLAGS) -o $@ $< bitcoind.exe: $(OBJS:obj/%=obj/%) - i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + i586-mingw32msvc-g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) @@ -100,7 +102,7 @@ i586-mingw32msvc-g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $< test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - i586-mingw32msvc-g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS) + i586-mingw32msvc-g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework-mt-s $(LIBS) clean:
--- a/src/makefile.mingw +++ b/src/makefile.mingw @@ -6,20 +6,21 @@ USE_IPV6:=1 INCLUDEPATHS= \ - -I"C:\boost-1.49.0-mgw" \ + -I"C:\boost-1.50.0-mgw" \ -I"C:\db-4.8.30.NC-mgw\build_unix" \ -I"C:\openssl-1.0.1b-mgw\include" LIBPATHS= \ - -L"C:\boost-1.49.0-mgw\stage\lib" \ + -L"C:\boost-1.50.0-mgw\stage\lib" \ -L"C:\db-4.8.30.NC-mgw\build_unix" \ -L"C:\openssl-1.0.1b-mgw" LIBS= \ - -l boost_system-mgw45-mt-s-1_49 \ - -l boost_filesystem-mgw45-mt-s-1_49 \ - -l boost_program_options-mgw45-mt-s-1_49 \ - -l boost_thread-mgw45-mt-s-1_49 \ + -l boost_system-mgw45-mt-s-1_50 \ + -l boost_filesystem-mgw45-mt-s-1_50 \ + -l boost_program_options-mgw45-mt-s-1_50 \ + -l boost_thread-mgw45-mt-s-1_50 \ + -l boost_chrono-mgw45-mt-s-1_50 \ -l db_cxx \ -l ssl \ -l crypto @@ -27,6 +28,7 @@ DEFS=-DWIN32 -D_WINDOWS -DBOOST_THREAD_USE_LIB -DBOOST_SPIRIT_THREADSAFE DEBUGFLAGS=-g CFLAGS=-mthreads -O2 -w -Wall -Wextra -Wformat -Wformat-security -Wno-unused-parameter $(DEBUGFLAGS) $(DEFS) $(INCLUDEPATHS) +LDFLAGS=-Wl,--dynamicbase -Wl,--nxcompat TESTDEFS = -DTEST_DATA_DIR=$(abspath test/data) @@ -84,7 +86,7 @@ g++ -c $(CFLAGS) -o $@ $< bitcoind.exe: $(OBJS:obj/%=obj/%) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) + g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ $(LIBS) TESTOBJS := $(patsubst test/%.cpp,obj-test/%.o,$(wildcard test/*.cpp)) @@ -92,7 +94,7 @@ g++ -c $(TESTDEFS) $(CFLAGS) -o $@ $< test_bitcoin.exe: $(TESTOBJS) $(filter-out obj/init.o,$(OBJS:obj/%=obj/%)) - g++ $(CFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS) + g++ $(CFLAGS) $(LDFLAGS) -o $@ $(LIBPATHS) $^ -lboost_unit_test_framework $(LIBS) clean: -del /Q bitcoind test_bitcoin
--- a/src/net.cpp +++ b/src/net.cpp @@ -233,8 +233,8 @@ bool fAlready = mapLocalHost.count(addr) > 0; LocalServiceInfo &info = mapLocalHost[addr]; if (!fAlready || nScore >= info.nScore) { - info.nScore = nScore; - info.nPort = addr.GetPort() + (fAlready ? 1 : 0); + info.nScore = nScore + (fAlready ? 1 : 0); + info.nPort = addr.GetPort(); } SetReachable(addr.GetNetwork()); }
--- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -20,9 +20,6 @@ #include <QSplashScreen> #include <QLibraryInfo> -#include <boost/interprocess/ipc/message_queue.hpp> -#include <boost/algorithm/string/predicate.hpp> - #if defined(BITCOIN_NEED_QT_PLUGINS) && !defined(_BITCOIN_QT_PLUGINS_INCLUDED) #define _BITCOIN_QT_PLUGINS_INCLUDED #define __INSURE__ @@ -116,35 +113,8 @@ #ifndef BITCOIN_QT_TEST int main(int argc, char *argv[]) { -// TODO: implement URI support on the Mac. -#if !defined(MAC_OSX) // Do this early as we don't want to bother initializing if we are just calling IPC - for (int i = 1; i < argc; i++) - { - if (boost::algorithm::istarts_with(argv[i], "bitcoin:")) - { - const char *strURI = argv[i]; - try { - boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); - if (mq.try_send(strURI, strlen(strURI), 0)) - // if URI could be sent to the message queue exit here - exit(0); - else - // if URI could not be sent to the message queue do a normal Bitcoin-Qt startup - break; - } - catch (boost::interprocess::interprocess_exception &ex) { - // don't log the "file not found" exception, because that's normal for - // the first start of the first instance - if (ex.get_error_code() != boost::interprocess::not_found_error) - { - printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); - break; - } - } - } - } -#endif + ipcScanRelay(argc, argv); // Internal string conversion is all UTF-8 QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); @@ -269,29 +239,10 @@ { window.show(); } -// TODO: implement URI support on the Mac. -#if !defined(MAC_OSX) // Place this here as guiref has to be defined if we don't want to lose URIs - ipcInit(); + ipcInit(argc, argv); - // Check for URI in argv - for (int i = 1; i < argc; i++) - { - if (boost::algorithm::istarts_with(argv[i], "bitcoin:")) - { - const char *strURI = argv[i]; - try { - boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); - mq.try_send(strURI, strlen(strURI), 0); - } - catch (boost::interprocess::interprocess_exception &ex) { - printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); - break; - } - } - } -#endif app.exec(); window.hide();
--- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -273,8 +273,7 @@ optionsAction = new QAction(QIcon(":/icons/options"), tr("&Options..."), this); optionsAction->setToolTip(tr("Modify configuration options for Bitcoin")); optionsAction->setMenuRole(QAction::PreferencesRole); - toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("Show/Hide &Bitcoin"), this); - toggleHideAction->setToolTip(tr("Show or hide the Bitcoin window")); + toggleHideAction = new QAction(QIcon(":/icons/bitcoin"), tr("&Show / Hide"), this); exportAction = new QAction(QIcon(":/icons/export"), tr("&Export..."), this); exportAction->setToolTip(tr("Export the data in the current tab to a file")); encryptWalletAction = new QAction(QIcon(":/icons/lock_closed"), tr("&Encrypt Wallet..."), this); @@ -463,7 +462,7 @@ { if(reason == QSystemTrayIcon::Trigger) { - // Click on system tray icon triggers "show/hide Bitcoin" + // Click on system tray icon triggers show/hide of the main window toggleHideAction->trigger(); } }
--- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -92,6 +92,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Get help for a command"), QT_TRANSLATE_NOOP("bitcoin-core", "How many blocks to check at startup (default: 2500, 0 = all)"), QT_TRANSLATE_NOOP("bitcoin-core", "How thorough the block verification is (0-6, default: 1)"), +QT_TRANSLATE_NOOP("bitcoin-core", "Importing blocks..."), QT_TRANSLATE_NOOP("bitcoin-core", "Imports blocks from external blk000?.dat file"), QT_TRANSLATE_NOOP("bitcoin-core", "Insufficient funds"), QT_TRANSLATE_NOOP("bitcoin-core", "Invalid -proxy address: '%s'"),
--- a/src/qt/forms/aboutdialog.ui +++ b/src/qt/forms/aboutdialog.ui @@ -65,9 +65,6 @@ <property name="text"> <string notr="true">0.3.666-beta</string> </property> - <property name="textFormat"> - <enum>Qt::RichText</enum> - </property> <property name="textInteractionFlags"> <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> </property> @@ -89,13 +86,25 @@ </layout> </item> <item> + <widget class="QLabel" name="copyrightLabel"> + <property name="cursor"> + <cursorShape>IBeamCursor</cursorShape> + </property> + <property name="text"> + <string>Copyright © 2009-2012 The Bitcoin developers</string> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item> <widget class="QLabel" name="label_2"> <property name="cursor"> <cursorShape>IBeamCursor</cursorShape> </property> <property name="text"> - <string>Copyright © 2009-2012 Bitcoin Developers - + <string> This is experimental software. Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php.
--- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -15,9 +15,13 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+44"/> - <source>Copyright © 2009-2012 Bitcoin Developers - + <location line="+41"/> + <source>Copyright © 2009-2012 The Bitcoin developers</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+13"/> + <source> This is experimental software. Distributed under the MIT/X11 software license, see the accompanying file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -286,22 +290,17 @@ <context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+218"/> + <location filename="../bitcoingui.cpp" line="+228"/> <source>Sign &message...</source> <translation type="unfinished"></translation> </message> <message> - <location line="+48"/> - <source>Show/Hide &Bitcoin</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+248"/> + <location line="+295"/> <source>Synchronizing with network...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-326"/> + <location line="-325"/> <source>&Overview</source> <translation type="unfinished"></translation> </message> @@ -376,7 +375,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> + <location line="+6"/> <source>&Encrypt Wallet...</source> <translation type="unfinished"></translation> </message> @@ -409,7 +408,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-55"/> + <location line="-54"/> <source>Send coins to a Bitcoin address</source> <translation type="unfinished"></translation> </message> @@ -434,12 +433,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> - <source>Show or hide the Bitcoin window</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+2"/> + <location line="+4"/> <source>Export the data in the current tab to a file</source> <translation type="unfinished"></translation> </message> @@ -469,12 +463,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-56"/> + <location line="-55"/> <source>&Verify message...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-151"/> + <location line="-160"/> <source>Bitcoin</source> <translation type="unfinished"></translation> </message> @@ -484,12 +478,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+186"/> + <location line="+195"/> <source>&About Bitcoin</source> <translation type="unfinished"></translation> </message> <message> - <location line="+44"/> + <location line="+9"/> + <source>&Show / Hide</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+34"/> <source>&File</source> <translation type="unfinished"></translation> </message> @@ -657,7 +656,7 @@ <translation type="unfinished"></translation> </message> <message> - <location filename="../bitcoin.cpp" line="+112"/> + <location filename="../bitcoin.cpp" line="+109"/> <source>A fatal error occurred. Bitcoin can no longer continue safely and will quit.</source> <translation type="unfinished"></translation> </message> @@ -741,7 +740,7 @@ <context> <name>GUIUtil::HelpMessageBox</name> <message> - <location filename="../guiutil.cpp" line="+425"/> + <location filename="../guiutil.cpp" line="+419"/> <location line="+12"/> <source>Bitcoin-Qt</source> <translation type="unfinished"></translation> @@ -960,7 +959,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+134"/> + <location line="+147"/> <location line="+9"/> <source>Warning</source> <translation type="unfinished"></translation> @@ -1256,7 +1255,7 @@ <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+123"/> + <location filename="../sendcoinsdialog.cpp" line="+124"/> <location line="+5"/> <location line="+5"/> <location line="+5"/> @@ -2106,7 +2105,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+81"/> + <location line="+82"/> <source>Usage:</source> <translation type="unfinished"></translation> </message> @@ -2121,12 +2120,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-9"/> + <location line="-10"/> <source>Get help for a command</source> <translation type="unfinished"></translation> </message> <message> - <location line="+19"/> + <location line="+20"/> <source>Options:</source> <translation type="unfinished"></translation> </message> @@ -2141,7 +2140,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-46"/> + <location line="-47"/> <source>Generate coins</source> <translation type="unfinished"></translation> </message> @@ -2151,7 +2150,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+59"/> + <location line="+60"/> <source>Specify data directory</source> <translation type="unfinished"></translation> </message> @@ -2181,27 +2180,27 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-32"/> + <location line="-33"/> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation type="unfinished"></translation> </message> <message> - <location line="+63"/> + <location line="+64"/> <source>Specify your own public address</source> <translation type="unfinished"></translation> </message> <message> - <location line="-74"/> + <location line="-75"/> <source>Bind to given address. Use [host]:port notation for IPv6</source> <translation type="unfinished"></translation> </message> <message> - <location line="+76"/> + <location line="+77"/> <source>Threshold for disconnecting misbehaving peers (default: 100)</source> <translation type="unfinished"></translation> </message> <message> - <location line="-104"/> + <location line="-105"/> <source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source> <translation type="unfinished"></translation> </message> @@ -2216,7 +2215,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+60"/> + <location line="+61"/> <source>Run in the background as a daemon and accept commands</source> <translation type="unfinished"></translation> </message> @@ -2226,7 +2225,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-92"/> + <location line="-93"/> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation type="unfinished"></translation> </message> @@ -2281,7 +2280,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+9"/> + <location line="+6"/> + <source>Importing blocks...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+4"/> <source>Invalid -tor address: '%s'</source> <translation type="unfinished"></translation> </message> @@ -2391,22 +2395,22 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-40"/> + <location line="-41"/> <source>Allow JSON-RPC connections from specified IP address</source> <translation type="unfinished"></translation> </message> <message> - <location line="+60"/> + <location line="+61"/> <source>Send commands to node running on <ip> (default: 127.0.0.1)</source> <translation type="unfinished"></translation> </message> <message> - <location line="-89"/> + <location line="-90"/> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+112"/> + <location line="+113"/> <source>Upgrade wallet to latest format</source> <translation type="unfinished"></translation> </message> @@ -2421,7 +2425,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-23"/> + <location line="-24"/> <source>How many blocks to check at startup (default: 2500, 0 = all)</source> <translation type="unfinished"></translation> </message> @@ -2431,7 +2435,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+1"/> + <location line="+2"/> <source>Imports blocks from external blk000?.dat file</source> <translation type="unfinished"></translation> </message> @@ -2451,17 +2455,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-109"/> + <location line="-110"/> <source>Acceptable ciphers (default: TLSv1+HIGH:!SSLv2:!aNULL:!eNULL:!AH:!3DES:@STRENGTH)</source> <translation type="unfinished"></translation> </message> <message> - <location line="+121"/> + <location line="+122"/> <source>This help message</source> <translation type="unfinished"></translation> </message> <message> - <location line="-118"/> + <location line="-119"/> <source>Cannot obtain a lock on data directory %s. Bitcoin is probably already running.</source> <translation type="unfinished"></translation> </message> @@ -2471,12 +2475,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+76"/> + <location line="+77"/> <source>Unable to bind to %s on this computer (bind returned error %d, %s)</source> <translation type="unfinished"></translation> </message> <message> - <location line="-68"/> + <location line="-69"/> <source>Connect through socks proxy</source> <translation type="unfinished"></translation> </message> @@ -2486,12 +2490,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+43"/> + <location line="+44"/> <source>Loading addresses...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-25"/> + <location line="-26"/> <source>Error loading blkindex.dat</source> <translation type="unfinished"></translation> </message> @@ -2506,17 +2510,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+71"/> + <location line="+72"/> <source>Wallet needed to be rewritten: restart Bitcoin to complete</source> <translation type="unfinished"></translation> </message> <message> - <location line="-73"/> + <location line="-74"/> <source>Error loading wallet.dat</source> <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> + <location line="+18"/> <source>Invalid -proxy address: '%s'</source> <translation type="unfinished"></translation> </message> @@ -2531,7 +2535,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-73"/> + <location line="-74"/> <source>Cannot resolve -bind address: '%s'</source> <translation type="unfinished"></translation> </message> @@ -2541,12 +2545,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+28"/> + <location line="+29"/> <source>Invalid amount for -paytxfee=<amount>: '%s'</source> <translation type="unfinished"></translation> </message> <message> - <location line="-13"/> + <location line="-14"/> <source>Error: could not start node</source> <translation type="unfinished"></translation> </message> @@ -2566,17 +2570,17 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+41"/> + <location line="+42"/> <source>Sending...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-99"/> + <location line="-100"/> <source>Error: The transaction was rejected. This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+74"/> + <location line="+75"/> <source>Invalid amount</source> <translation type="unfinished"></translation> </message> @@ -2591,7 +2595,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="-45"/> + <location line="-46"/> <source>Add a node to connect to and attempt to keep the connection open</source> <translation type="unfinished"></translation> </message> @@ -2611,12 +2615,12 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+18"/> + <location line="+19"/> <source>Loading wallet...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-38"/> + <location line="-39"/> <source>Cannot downgrade wallet</source> <translation type="unfinished"></translation> </message> @@ -2631,22 +2635,22 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+45"/> + <location line="+46"/> <source>Rescanning...</source> <translation type="unfinished"></translation> </message> <message> - <location line="-39"/> + <location line="-40"/> <source>Done loading</source> <translation type="unfinished"></translation> </message> <message> - <location line="+63"/> + <location line="+64"/> <source>To use the %s option</source> <translation type="unfinished"></translation> </message> <message> - <location line="-132"/> + <location line="-133"/> <source>%s, you must set a rpcpassword in the configuration file: %s It is recommended you use the following random password:
--- a/src/qt/qtipcserver.cpp +++ b/src/qt/qtipcserver.cpp @@ -2,11 +2,18 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <boost/version.hpp> +#if defined(WIN32) && BOOST_VERSION == 104900 +#define BOOST_INTERPROCESS_HAS_WINDOWS_KERNEL_BOOTTIME +#define BOOST_INTERPROCESS_HAS_KERNEL_BOOTTIME +#endif + #include "qtipcserver.h" #include "guiconstants.h" #include "ui_interface.h" #include "util.h" +#include <boost/algorithm/string/predicate.hpp> #include <boost/date_time/posix_time/posix_time.hpp> #include <boost/interprocess/ipc/message_queue.hpp> #include <boost/version.hpp> @@ -19,15 +26,52 @@ using namespace boost::interprocess; using namespace boost::posix_time; -static void ipcThread2(void* pArg); - #ifdef MAC_OSX // URI handling not implemented on OSX yet -void ipcInit() { } +void ipcScanRelay(int argc, char *argv[]) { } +void ipcInit(int argc, char *argv[]) { } #else +static void ipcThread2(void* pArg); + +static bool ipcScanCmd(int argc, char *argv[], bool fRelay) +{ + // Check for URI in argv + bool fSent = false; + for (int i = 1; i < argc; i++) + { + if (boost::algorithm::istarts_with(argv[i], "bitcoin:")) + { + const char *strURI = argv[i]; + try { + boost::interprocess::message_queue mq(boost::interprocess::open_only, BITCOINURI_QUEUE_NAME); + if (mq.try_send(strURI, strlen(strURI), 0)) + fSent = true; + else if (fRelay) + break; + } + catch (boost::interprocess::interprocess_exception &ex) { + // don't log the "file not found" exception, because that's normal for + // the first start of the first instance + if (ex.get_error_code() != boost::interprocess::not_found_error || !fRelay) + { + printf("main() - boost interprocess exception #%d: %s\n", ex.get_error_code(), ex.what()); + break; + } + } + } + } + return fSent; +} + +void ipcScanRelay(int argc, char *argv[]) +{ + if (ipcScanCmd(argc, argv, true)) + exit(0); +} + static void ipcThread(void* pArg) { IMPLEMENT_RANDOMIZE_STACK(ipcThread(pArg)); @@ -75,7 +119,7 @@ delete mq; } -void ipcInit() +void ipcInit(int argc, char *argv[]) { message_queue* mq = NULL; char buffer[MAX_URI_LENGTH + 1] = ""; @@ -113,6 +157,8 @@ delete mq; return; } + + ipcScanCmd(argc, argv, false); } #endif
--- a/src/qt/qtipcserver.h +++ b/src/qt/qtipcserver.h @@ -4,6 +4,7 @@ // Define Bitcoin-Qt message queue name #define BITCOINURI_QUEUE_NAME "BitcoinURI" -void ipcInit(); +void ipcScanRelay(int argc, char *argv[]); +void ipcInit(int argc, char *argv[]); #endif // QTIPCSERVER_H
--- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -13,7 +13,6 @@ #include <QUrl> #include <QScrollBar> -#include <boost/tokenizer.hpp> #include <openssl/crypto.h> // TODO: make it possible to filter out categories (esp debug messages when implemented) @@ -54,34 +53,108 @@ // Nothing to do } +/** + * Split shell command line into a list of arguments. Aims to emulate \c bash and friends. + * + * - Arguments are delimited with whitespace + * - Extra whitespace at the beginning and end and between arguments will be ignored + * - Text can be "double" or 'single' quoted + * - The backslash \c \ is used as escape character + * - Outside quotes, any character can be escaped + * - Within double quotes, only escape \c " and backslashes before a \c " or another backslash + * - Within single quotes, no escaping is possible and no special interpretation takes place + * + * @param[out] args Parsed arguments will be appended to this list + * @param[in] strCommand Command line to split + */ +bool parseCommandLine(std::vector<std::string> &args, const std::string &strCommand) +{ + enum CmdParseState + { + STATE_EATING_SPACES, + STATE_ARGUMENT, + STATE_SINGLEQUOTED, + STATE_DOUBLEQUOTED, + STATE_ESCAPE_OUTER, + STATE_ESCAPE_DOUBLEQUOTED + } state = STATE_EATING_SPACES; + std::string curarg; + foreach(char ch, strCommand) + { + switch(state) + { + case STATE_ARGUMENT: // In or after argument + case STATE_EATING_SPACES: // Handle runs of whitespace + switch(ch) + { + case '"': state = STATE_DOUBLEQUOTED; break; + case '\'': state = STATE_SINGLEQUOTED; break; + case '\\': state = STATE_ESCAPE_OUTER; break; + case ' ': case '\n': case '\t': + if(state == STATE_ARGUMENT) // Space ends argument + { + args.push_back(curarg); + curarg.clear(); + } + state = STATE_EATING_SPACES; + break; + default: curarg += ch; state = STATE_ARGUMENT; + } + break; + case STATE_SINGLEQUOTED: // Single-quoted string + switch(ch) + { + case '\'': state = STATE_ARGUMENT; break; + default: curarg += ch; + } + break; + case STATE_DOUBLEQUOTED: // Double-quoted string + switch(ch) + { + case '"': state = STATE_ARGUMENT; break; + case '\\': state = STATE_ESCAPE_DOUBLEQUOTED; break; + default: curarg += ch; + } + break; + case STATE_ESCAPE_OUTER: // '\' outside quotes + curarg += ch; state = STATE_ARGUMENT; + break; + case STATE_ESCAPE_DOUBLEQUOTED: // '\' in double-quoted text + if(ch != '"' && ch != '\\') curarg += '\\'; // keep '\' for everything but the quote and '\' itself + curarg += ch; state = STATE_DOUBLEQUOTED; + break; + } + } + switch(state) // final state + { + case STATE_EATING_SPACES: + return true; + case STATE_ARGUMENT: + args.push_back(curarg); + return true; + default: // ERROR to end in one of the other states + return false; + } +} + void RPCExecutor::request(const QString &command) { - // Parse shell-like command line into separate arguments - std::string strMethod; - std::vector<std::string> strParams; - try { - boost::escaped_list_separator<char> els('\\',' ','\"'); - std::string strCommand = command.toStdString(); - boost::tokenizer<boost::escaped_list_separator<char> > tok(strCommand, els); - - int n = 0; - for(boost::tokenizer<boost::escaped_list_separator<char> >::iterator beg=tok.begin(); beg!=tok.end();++beg,++n) - { - if(n == 0) // First parameter is the command - strMethod = *beg; - else - strParams.push_back(*beg); - } - } - catch(boost::escaped_list_error &e) + std::vector<std::string> args; + if(!parseCommandLine(args, command.toStdString())) { - emit reply(RPCConsole::CMD_ERROR, QString("Parse error")); + emit reply(RPCConsole::CMD_ERROR, QString("Parse error: unbalanced ' or \"")); return; } - - try { + if(args.empty()) + return; // Nothing to do + try + { std::string strPrint; - json_spirit::Value result = tableRPC.execute(strMethod, RPCConvertValues(strMethod, strParams)); + // Convert argument list to JSON objects in method-dependent way, + // and pass it along with the method name to the dispatcher. + json_spirit::Value result = tableRPC.execute( + args[0], + RPCConvertValues(args[0], std::vector<std::string>(args.begin() + 1, args.end()))); // Format result reply if (result.type() == json_spirit::null_type) @@ -95,7 +168,16 @@ } catch (json_spirit::Object& objError) { - emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); + try // Nice formatting for standard-format error + { + int code = find_value(objError, "code").get_int(); + std::string message = find_value(objError, "message").get_str(); + emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(message) + " (code " + QString::number(code) + ")"); + } + catch(std::runtime_error &) // raised when converting to invalid type, i.e. missing code or message + { // Show raw JSON object + emit reply(RPCConsole::CMD_ERROR, QString::fromStdString(write_string(json_spirit::Value(objError), false))); + } } catch (std::exception& e) {
--- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -225,6 +225,10 @@ const Value& modeval = find_value(oparam, "mode"); if (modeval.type() == str_type) strMode = modeval.get_str(); + else if (modeval.type() == null_type) + { + /* Do nothing */ + } else throw JSONRPCError(-8, "Invalid mode"); }
--- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1006,7 +1006,8 @@ Array ret; - CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(strAccount); + std::list<CAccountingEntry> acentries; + CWallet::TxItems txOrdered = pwalletMain->OrderedTxItems(acentries, strAccount); // iterate backwards until we have nCount items to return: for (CWallet::TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it)
--- a/src/version.h +++ b/src/version.h @@ -12,8 +12,8 @@ // These need to be macros, as version.cpp's voodoo requires it #define CLIENT_VERSION_MAJOR 0 -#define CLIENT_VERSION_MINOR 6 -#define CLIENT_VERSION_REVISION 99 +#define CLIENT_VERSION_MINOR 7 +#define CLIENT_VERSION_REVISION 0 #define CLIENT_VERSION_BUILD 0 static const int CLIENT_VERSION =
--- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -291,8 +291,7 @@ return true; } -CWallet::TxItems -CWallet::OrderedTxItems(std::string strAccount) +CWallet::TxItems CWallet::OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount) { CWalletDB walletdb(strWalletFile); @@ -306,7 +305,7 @@ CWalletTx* wtx = &((*it).second); txOrdered.insert(make_pair(wtx->nOrderPos, TxPair(wtx, (CAccountingEntry*)0))); } - list<CAccountingEntry> acentries; + acentries.clear(); walletdb.ListAccountCreditDebit(strAccount, acentries); BOOST_FOREACH(CAccountingEntry& entry, acentries) { @@ -375,7 +374,8 @@ { // Tolerate times up to the last timestamp in the wallet not more than 5 minutes into the future int64 latestTolerated = latestNow + 300; - TxItems txOrdered = OrderedTxItems(); + std::list<CAccountingEntry> acentries; + TxItems txOrdered = OrderedTxItems(acentries); for (TxItems::reverse_iterator it = txOrdered.rbegin(); it != txOrdered.rend(); ++it) { CWalletTx *const pwtx = (*it).second.first;
--- a/src/wallet.h +++ b/src/wallet.h @@ -146,7 +146,12 @@ typedef std::pair<CWalletTx*, CAccountingEntry*> TxPair; typedef std::multimap<int64, TxPair > TxItems; - TxItems OrderedTxItems(std::string strAccount = ""); + + /** Get the wallet's activity log + @return multimap of ordered transactions and accounting entries + @warning Returned pointers are *only* valid within the scope of passed acentries + */ + TxItems OrderedTxItems(std::list<CAccountingEntry>& acentries, std::string strAccount = ""); void MarkDirty(); bool AddToWallet(const CWalletTx& wtxIn);