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 &amp;message...</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+48"/>
-        <source>Show/Hide &amp;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>&amp;Overview</source>
         <translation type="unfinished"></translation>
     </message>
@@ -376,7 +375,7 @@
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+7"/>
+        <location line="+6"/>
         <source>&amp;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>&amp;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>&amp;About Bitcoin</source>
         <translation type="unfinished"></translation>
     </message>
     <message>
-        <location line="+44"/>
+        <location line="+9"/>
+        <source>&amp;Show / Hide</source>
+        <translation type="unfinished"></translation>
+    </message>
+    <message>
+        <location line="+34"/>
         <source>&amp;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: &apos;%s&apos;</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 &lt;ip&gt; (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: &apos;%s&apos;</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: &apos;%s&apos;</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=&lt;amount&gt;: &apos;%s&apos;</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);