aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml5
-rwxr-xr-xautogen.sh3
-rw-r--r--build-aux/m4/bitcoin_qt.m432
-rw-r--r--configure.ac36
-rw-r--r--contrib/gitian-descriptors/boost-win.yml2
-rw-r--r--contrib/gitian-descriptors/deps-win.yml4
-rw-r--r--contrib/gitian-descriptors/gitian-win.yml4
-rw-r--r--contrib/gitian-descriptors/protobuf-win.yml2
-rw-r--r--contrib/gitian-descriptors/qt-linux.yml4
-rw-r--r--contrib/gitian-descriptors/qt-win.yml2
-rw-r--r--depends/config.site.in4
-rwxr-xr-xqa/rpc-tests/send.sh2
-rwxr-xr-xqa/rpc-tests/walletbackup.sh2
-rw-r--r--src/Makefile.am2
-rw-r--r--src/bitcoin-tx.cpp2
-rw-r--r--src/init.cpp3
-rw-r--r--src/main.cpp65
-rw-r--r--src/main.h16
-rw-r--r--src/miner.cpp2
-rw-r--r--src/qt/bitcoinstrings.cpp16
-rw-r--r--src/qt/locale/bitcoin_en.ts346
-rw-r--r--src/rpcrawtransaction.cpp7
-rw-r--r--src/script/interpreter.cpp89
-rw-r--r--src/script/interpreter.h35
-rw-r--r--src/script/sigcache.cpp88
-rw-r--r--src/script/sigcache.h26
-rw-r--r--src/script/sign.cpp8
-rw-r--r--src/script/standard.cpp15
-rw-r--r--src/test/multisig_tests.cpp18
-rw-r--r--src/test/script_P2SH_tests.cpp4
-rw-r--r--src/test/script_tests.cpp36
-rw-r--r--src/test/transaction_tests.cpp5
32 files changed, 472 insertions, 413 deletions
diff --git a/.travis.yml b/.travis.yml
index eae07ead8..89b223865 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -31,7 +31,7 @@ matrix:
- compiler: "true 3"
env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
- compiler: "true 4"
- env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash"
- compiler: "true 5"
env: HOST=x86_64-apple-darwin11 PACKAGES="gcc-multilib g++-multilib cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.7 GOAL="deploy"
- compiler: "true 6"
@@ -48,11 +48,12 @@ before_script:
- if [ -n "$OSX_SDK" -a -f depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz ]; then tar -C depends/SDKs -xf depends/sdk-sources/MacOSX${OSX_SDK}.sdk.tar.gz; fi
- make $MAKEJOBS -C depends HOST=$HOST $DEP_OPTS || (echo "Build failure. Verbose build follows." && make -C depends V=1 HOST=$HOST $DEP_OPTS)
script:
+ - if [ -n "$USE_SHELL" ]; then export CONFIG_SHELL="$USE_SHELL"; fi
- OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
- BITCOIN_CONFIG_ALL="--disable-dependency-tracking --prefix=$TRAVIS_BUILD_DIR/depends/$HOST --bindir=$OUTDIR/bin --libdir=$OUTDIR/lib"
- depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE
- if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then export CCACHE_READONLY=1; fi
- - ./autogen.sh
+ - test -n "$USE_SHELL" && eval '"$USE_SHELL" -c "./autogen.sh"' || ./autogen.sh
- ./configure --cache-file=config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false)
- make distdir PACKAGE=bitcoin VERSION=$HOST
- cd bitcoin-$HOST
diff --git a/autogen.sh b/autogen.sh
index ddfc09607..3e26a1830 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -3,6 +3,7 @@ set -e
srcdir="$(dirname $0)"
cd "$srcdir"
if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then
- export LIBTOOLIZE="${GLIBTOOLIZE}"
+ LIBTOOLIZE="${GLIBTOOLIZE}"
+ export LIBTOOLIZE
fi
autoreconf --install --force --warnings=all
diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4
index 71b148489..2a7226265 100644
--- a/build-aux/m4/bitcoin_qt.m4
+++ b/build-aux/m4/bitcoin_qt.m4
@@ -84,7 +84,7 @@ dnl Outputs: bitcoin_enable_qt, bitcoin_enable_qt_dbus, bitcoin_enable_qt_test
AC_DEFUN([BITCOIN_QT_CONFIGURE],[
use_pkgconfig=$1
- if test x$use_pkgconfig == x; then
+ if test x$use_pkgconfig = x; then
use_pkgconfig=yes
fi
@@ -106,9 +106,9 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
BITCOIN_QT_CHECK([
TEMP_CPPFLAGS=$CPPFLAGS
CPPFLAGS=$QT_INCLUDES
- if test x$bitcoin_qt_got_major_vers == x5; then
+ if test x$bitcoin_qt_got_major_vers = x5; then
_BITCOIN_QT_IS_STATIC
- if test x$bitcoin_cv_static_qt == xyes; then
+ if test x$bitcoin_cv_static_qt = xyes; then
AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
if test x$qt_plugin_path != x; then
QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
@@ -118,14 +118,14 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
PKG_CHECK_MODULES([QTPLATFORM], [Qt5PlatformSupport], [QT_LIBS="$QTPLATFORM_LIBS $QT_LIBS"])
fi
_BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets])
- if test x$TARGET_OS == xwindows; then
+ if test x$TARGET_OS = xwindows; then
_BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows])
AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows])
- elif test x$TARGET_OS == xlinux; then
+ elif test x$TARGET_OS = xlinux; then
PKG_CHECK_MODULES([X11XCB], [x11-xcb], [QT_LIBS="$X11XCB_LIBS $QT_LIBS"])
_BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QXcbIntegrationPlugin)],[-lqxcb -lxcb-static])
AC_DEFINE(QT_QPA_PLATFORM_XCB, 1, [Define this symbol if the qt platform is xcb])
- elif test x$TARGET_OS == xdarwin; then
+ elif test x$TARGET_OS = xdarwin; then
if test x$use_pkgconfig = xyes; then
PKG_CHECK_MODULES([QTPRINT], [Qt5PrintSupport], [QT_LIBS="$QTPRINT_LIBS $QT_LIBS"])
fi
@@ -135,7 +135,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
fi
fi
else
- if test x$TARGET_OS == xwindows; then
+ if test x$TARGET_OS = xwindows; then
AC_DEFINE(QT_STATICPLUGIN, 1, [Define this symbol if qt plugins are static])
if test x$qt_plugin_path != x; then
QT_LIBS="$QT_LIBS -L$qt_plugin_path/accessible"
@@ -196,7 +196,7 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[
if test x$use_dbus = xyes && test x$have_qt_dbus = xno; then
AC_MSG_ERROR("libQtDBus not found. Install libQtDBus or remove --with-qtdbus.")
fi
- if test x$LUPDATE == x; then
+ if test x$LUPDATE = x; then
AC_MSG_WARN("lupdate is required to update qt translations")
fi
],[
@@ -291,10 +291,10 @@ dnl Outputs: have_qt_test and have_qt_dbus are set (if applicable) to yes|no.
AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[
m4_ifdef([PKG_CHECK_MODULES],[
auto_priority_version=$1
- if test x$auto_priority_version == x; then
+ if test x$auto_priority_version = x; then
auto_priority_version=qt5
fi
- if test x$bitcoin_qt_want_version == xqt5 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt5 ); then
+ if test x$bitcoin_qt_want_version = xqt5 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt5 ); then
QT_LIB_PREFIX=Qt5
bitcoin_qt_got_major_vers=5
else
@@ -304,14 +304,14 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITH_PKGCONFIG],[
qt5_modules="Qt5Core Qt5Gui Qt5Network Qt5Widgets"
qt4_modules="QtCore QtGui QtNetwork"
BITCOIN_QT_CHECK([
- if test x$bitcoin_qt_want_version == xqt5 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt5 ); then
+ if test x$bitcoin_qt_want_version = xqt5 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt5 ); then
PKG_CHECK_MODULES([QT], [$qt5_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes],[have_qt=no])
- elif test x$bitcoin_qt_want_version == xqt4 || ( test x$bitcoin_qt_want_version == xauto && test x$auto_priority_version == xqt4 ); then
+ elif test x$bitcoin_qt_want_version = xqt4 || ( test x$bitcoin_qt_want_version = xauto && test x$auto_priority_version = xqt4 ); then
PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes], [have_qt=no])
fi
dnl qt version is set to 'auto' and the preferred version wasn't found. Now try the other.
- if test x$have_qt == xno && test x$bitcoin_qt_want_version == xauto; then
+ if test x$have_qt = xno && test x$bitcoin_qt_want_version = xauto; then
if test x$auto_priority_version = x$qt5; then
PKG_CHECK_MODULES([QT], [$qt4_modules], [QT_INCLUDES="$QT_CFLAGS"; have_qt=yes; QT_LIB_PREFIX=Qt; bitcoin_qt_got_major_vers=4], [have_qt=no])
else
@@ -358,7 +358,7 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[
if test x$bitcoin_qt_want_version = xauto; then
_BITCOIN_QT_CHECK_QT5
fi
- if test x$bitcoin_cv_qt5 == xyes || test x$bitcoin_qt_want_version = xqt5; then
+ if test x$bitcoin_cv_qt5 = xyes || test x$bitcoin_qt_want_version = xqt5; then
QT_LIB_PREFIX=Qt5
bitcoin_qt_got_major_vers=5
else
@@ -373,7 +373,7 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[
LIBS="$LIBS -L$qt_lib_path"
fi
- if test x$TARGET_OS == xwindows; then
+ if test x$TARGET_OS = xwindows; then
AC_CHECK_LIB([imm32], [main],, BITCOIN_QT_FAIL(libimm32 not found))
fi
])
@@ -385,7 +385,7 @@ AC_DEFUN([_BITCOIN_QT_FIND_LIBS_WITHOUT_PKGCONFIG],[
BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Core] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXCore not found)))
BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Gui] ,[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXGui not found)))
BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Network],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXNetwork not found)))
- if test x$bitcoin_qt_got_major_vers == x5; then
+ if test x$bitcoin_qt_got_major_vers = x5; then
BITCOIN_QT_CHECK(AC_CHECK_LIB([${QT_LIB_PREFIX}Widgets],[main],,BITCOIN_QT_FAIL(lib$QT_LIB_PREFIXWidgets not found)))
fi
QT_LIBS="$LIBS"
diff --git a/configure.ac b/configure.ac
index abf9f39e6..87c7833bc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -240,7 +240,7 @@ case $host in
AC_CHECK_PROG([BREW],brew, brew)
if test x$BREW = xbrew; then
- dnl These Homebrew packages may be bottled, meaning that they won't be found
+ dnl These Homebrew packages may be keg-only, meaning that they won't be found
dnl in expected paths because they may conflict with system files. Ask
dnl Homebrew where each one is located, then adjust paths accordingly.
dnl It's safe to add these paths even if the functionality is disabled by
@@ -250,14 +250,16 @@ case $host in
bdb_prefix=`$BREW --prefix berkeley-db4 2>/dev/null`
qt5_prefix=`$BREW --prefix qt5 2>/dev/null`
if test x$openssl_prefix != x; then
- export PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ PKG_CONFIG_PATH="$openssl_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
fi
if test x$bdb_prefix != x; then
CPPFLAGS="$CPPFLAGS -I$bdb_prefix/include"
LIBS="$LIBS -L$bdb_prefix/lib"
fi
if test x$qt5_prefix != x; then
- export PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ PKG_CONFIG_PATH="$qt5_prefix/lib/pkgconfig:$PKG_CONFIG_PATH"
+ export PKG_CONFIG_PATH
fi
fi
else
@@ -287,7 +289,7 @@ if test x$use_comparison_tool != xno; then
fi
if test x$use_comparison_tool_reorg_tests != xno; then
- if test x$use_comparison_tool == x; then
+ if test x$use_comparison_tool = x; then
AC_MSG_ERROR("comparison tool reorg tests but comparison tool was not specified")
fi
AC_SUBST(COMPARISON_TOOL_REORG_TESTS, 1)
@@ -295,20 +297,20 @@ else
AC_SUBST(COMPARISON_TOOL_REORG_TESTS, 0)
fi
-if test x$use_lcov == xyes; then
- if test x$LCOV == x; then
+if test x$use_lcov = xyes; then
+ if test x$LCOV = x; then
AC_MSG_ERROR("lcov testing requested but lcov not found")
fi
- if test x$GCOV == x; then
+ if test x$GCOV = x; then
AC_MSG_ERROR("lcov testing requested but gcov not found")
fi
- if test x$JAVA == x; then
+ if test x$JAVA = x; then
AC_MSG_ERROR("lcov testing requested but java not found")
fi
- if test x$GENHTML == x; then
+ if test x$GENHTML = x; then
AC_MSG_ERROR("lcov testing requested but genhtml not found")
fi
- if test x$use_comparison_tool == x; then
+ if test x$use_comparison_tool = x; then
AC_MSG_ERROR("lcov testing requested but comparison tool was not specified")
fi
LCOV="$LCOV --gcov-tool=$GCOV"
@@ -607,7 +609,7 @@ BITCOIN_QT_INIT
if test x$use_pkgconfig = xyes; then
- if test x"$PKG_CONFIG" == "x"; then
+ if test x"$PKG_CONFIG" = "x"; then
AC_MSG_ERROR(pkg-config not found.)
fi
@@ -721,7 +723,7 @@ if test x$bitcoin_enable_qt != xno; then
dnl enable qr support
AC_MSG_CHECKING([whether to build GUI with support for QR codes])
if test x$have_qrencode = xno; then
- if test x$use_qr == xyes; then
+ if test x$use_qr = xyes; then
AC_MSG_ERROR("QR support requested but cannot be built. use --without-qrencode")
fi
AC_MSG_RESULT(no)
@@ -735,7 +737,7 @@ if test x$bitcoin_enable_qt != xno; then
fi
fi
- if test x$XGETTEXT == x; then
+ if test x$XGETTEXT = x; then
AC_MSG_WARN("xgettext is required to update qt translations")
fi
@@ -770,12 +772,12 @@ fi
AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin])
AM_CONDITIONAL([BUILD_DARWIN], [test x$BUILD_OS = xdarwin])
AM_CONDITIONAL([TARGET_WINDOWS], [test x$TARGET_OS = xwindows])
-AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet == xyes])
-AM_CONDITIONAL([ENABLE_TESTS],[test x$use_tests == xyes])
-AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt == xyes])
+AM_CONDITIONAL([ENABLE_WALLET],[test x$enable_wallet = xyes])
+AM_CONDITIONAL([ENABLE_TESTS],[test x$use_tests = xyes])
+AM_CONDITIONAL([ENABLE_QT],[test x$bitcoin_enable_qt = xyes])
AM_CONDITIONAL([ENABLE_QT_TESTS],[test x$use_tests$bitcoin_enable_qt_test = xyesyes])
AM_CONDITIONAL([USE_QRCODE], [test x$use_qr = xyes])
-AM_CONDITIONAL([USE_LCOV],[test x$use_lcov == xyes])
+AM_CONDITIONAL([USE_LCOV],[test x$use_lcov = xyes])
AM_CONDITIONAL([USE_COMPARISON_TOOL],[test x$use_comparison_tool != xno])
AM_CONDITIONAL([USE_COMPARISON_TOOL_REORG_TESTS],[test x$use_comparison_tool_reorg_test != xno])
AM_CONDITIONAL([GLIBC_BACK_COMPAT],[test x$use_glibc_compat = xyes])
diff --git a/contrib/gitian-descriptors/boost-win.yml b/contrib/gitian-descriptors/boost-win.yml
index db5d6bab1..347952e3a 100644
--- a/contrib/gitian-descriptors/boost-win.yml
+++ b/contrib/gitian-descriptors/boost-win.yml
@@ -29,7 +29,7 @@ script: |
#
INSTALLPREFIX=$HOME/staging${BITS}
BUILDDIR=$HOME/build${BITS}
- if [ "$BITS" == "32" ]; then
+ if [ "x$BITS" = "x32" ]; then
HOST=i686-w64-mingw32
else
HOST=x86_64-w64-mingw32
diff --git a/contrib/gitian-descriptors/deps-win.yml b/contrib/gitian-descriptors/deps-win.yml
index fabc2949e..fe02950ef 100644
--- a/contrib/gitian-descriptors/deps-win.yml
+++ b/contrib/gitian-descriptors/deps-win.yml
@@ -39,7 +39,7 @@ script: |
#
INSTALLPREFIX=$HOME/staging${BITS}
BUILDDIR=$HOME/build${BITS}
- if [ "$BITS" == "32" ]; then
+ if [ "x$BITS" = "x32" ]; then
HOST=i686-w64-mingw32
else
HOST=x86_64-w64-mingw32
@@ -50,7 +50,7 @@ script: |
#
tar xzf $INDIR/openssl-1.0.1h.tar.gz
cd openssl-1.0.1h
- if [ "$BITS" == "32" ]; then
+ if [ "x$BITS" = "x32" ]; then
OPENSSL_TGT=mingw
else
OPENSSL_TGT=mingw64
diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml
index 245f15cca..b2795c537 100644
--- a/contrib/gitian-descriptors/gitian-win.yml
+++ b/contrib/gitian-descriptors/gitian-win.yml
@@ -50,7 +50,7 @@ script: |
STAGING=$HOME/staging${BITS}
BUILDDIR=$HOME/build${BITS}
BINDIR=$OUTDIR/$BITS
- if [ "$BITS" == "32" ]; then
+ if [ "x$BITS" = "x32" ]; then
HOST=i686-w64-mingw32
else
HOST=x86_64-w64-mingw32
@@ -63,7 +63,7 @@ script: |
unzip $INDIR/boost-win${BITS}-1.55.0-gitian-r6.zip
unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r13.zip
unzip $INDIR/protobuf-win${BITS}-2.5.0-gitian-r4.zip
- if [ "$NEEDDIST" == "1" ]; then
+ if [ "x$NEEDDIST" = "x1" ]; then
# Make source code archive which is architecture independent so it only needs to be done once
cd $HOME/build/bitcoin
./autogen.sh
diff --git a/contrib/gitian-descriptors/protobuf-win.yml b/contrib/gitian-descriptors/protobuf-win.yml
index d2fdcaa7f..1b7af0884 100644
--- a/contrib/gitian-descriptors/protobuf-win.yml
+++ b/contrib/gitian-descriptors/protobuf-win.yml
@@ -26,7 +26,7 @@ script: |
#
INSTALLPREFIX=$HOME/staging${BITS}
BUILDDIR=$HOME/build${BITS}
- if [ "$BITS" == "32" ]; then
+ if [ "x$BITS" = "x32" ]; then
HOST=i686-w64-mingw32
else
HOST=x86_64-w64-mingw32
diff --git a/contrib/gitian-descriptors/qt-linux.yml b/contrib/gitian-descriptors/qt-linux.yml
index b163b4bb8..fd86b4df1 100644
--- a/contrib/gitian-descriptors/qt-linux.yml
+++ b/contrib/gitian-descriptors/qt-linux.yml
@@ -18,7 +18,7 @@ files:
script: |
export FAKETIME=$REFERENCE_DATETIME
export TZ=UTC
- if [ "$GBUILD_BITS" == "32" ]; then
+ if [ "x$GBUILD_BITS" = "x32" ]; then
ARCH='i386-linux-gnu'
else
ARCH='x86_64-linux-gnu'
@@ -74,7 +74,7 @@ script: |
#endif
' > $QCONFIG
- if [ "$GBUILD_BITS" == "32" ]; then
+ if [ "x$GBUILD_BITS" = "x32" ]; then
echo '
/* Machine byte-order */
#define Q_BIG_ENDIAN 4321
diff --git a/contrib/gitian-descriptors/qt-win.yml b/contrib/gitian-descriptors/qt-win.yml
index 7000c7005..57bc4c318 100644
--- a/contrib/gitian-descriptors/qt-win.yml
+++ b/contrib/gitian-descriptors/qt-win.yml
@@ -38,7 +38,7 @@ script: |
INSTALLPREFIX=$HOME/staging${BITS}
BUILDDIR=$HOME/build${BITS}
DEPSDIR=$HOME/deps${BITS}
- if [ "$BITS" == "32" ]; then
+ if [ "x$BITS" = "x32" ]; then
HOST=i686-w64-mingw32
else
HOST=x86_64-w64-mingw32
diff --git a/depends/config.site.in b/depends/config.site.in
index 3426050cd..df076956b 100644
--- a/depends/config.site.in
+++ b/depends/config.site.in
@@ -34,12 +34,12 @@ if test -z $with_gui && test -n "@no_qt@"; then
with_gui=no
fi
-if test @host_os@ == darwin; then
+if test x@host_os@ = xdarwin; then
BREW=no
PORT=no
fi
-if test @host_os@ == mingw32; then
+if test x@host_os@ = xmingw32; then
if test -z $with_qt_incdir; then
with_qt_incdir=$prefix/include
fi
diff --git a/qa/rpc-tests/send.sh b/qa/rpc-tests/send.sh
index bfbf791d0..8c0f11459 100755
--- a/qa/rpc-tests/send.sh
+++ b/qa/rpc-tests/send.sh
@@ -14,7 +14,7 @@ if [ $# -eq 0 ]; then
exit 0
fi
-if [ $1 == "-STOP" ]; then
+if [ $1 = "-STOP" ]; then
if [ -s ${PIDFILE} ]; then
kill -s ${SIGNAL} $(<${PIDFILE})
fi
diff --git a/qa/rpc-tests/walletbackup.sh b/qa/rpc-tests/walletbackup.sh
index 744467098..b88d5920f 100755
--- a/qa/rpc-tests/walletbackup.sh
+++ b/qa/rpc-tests/walletbackup.sh
@@ -149,7 +149,7 @@ echo "Creating transactions..."
function S {
TXID=$( $CLI -datadir=${D}/node${1} sendtoaddress ${2} "${3}" 0 )
- if [[ $TXID == "" ]] ; then
+ if [ x$TXID = x ] ; then
echoerr "node${1}: error sending ${3} btc"
echo -n "node${1} balance: "
$CLI -datadir=${D}/node${1} getbalance "*" 0
diff --git a/src/Makefile.am b/src/Makefile.am
index bd6f1ba0d..155adfef7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -103,6 +103,7 @@ BITCOIN_CORE_H = \
script/compressor.h \
script/interpreter.h \
script/script.h \
+ script/sigcache.h \
script/sign.h \
script/standard.h \
serialize.h \
@@ -218,6 +219,7 @@ libbitcoin_common_a_SOURCES = \
script/compressor.cpp \
script/interpreter.cpp \
script/script.cpp \
+ script/sigcache.cpp \
script/sign.cpp \
script/standard.cpp \
$(BITCOIN_CORE_H)
diff --git a/src/bitcoin-tx.cpp b/src/bitcoin-tx.cpp
index a61b4fe29..a198eb586 100644
--- a/src/bitcoin-tx.cpp
+++ b/src/bitcoin-tx.cpp
@@ -435,7 +435,7 @@ static void MutateTxSign(CMutableTransaction& tx, const string& flagStr)
BOOST_FOREACH(const CTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
}
- if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS))
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i)))
fComplete = false;
}
diff --git a/src/init.cpp b/src/init.cpp
index 980c589b2..36ba13b94 100644
--- a/src/init.cpp
+++ b/src/init.cpp
@@ -237,7 +237,7 @@ std::string HelpMessage(HelpMessageMode mode)
#if !defined(WIN32)
strUsage += " -sysperms " + _("Create new files with system default permissions, instead of umask 077 (only effective with disabled wallet functionality)") + "\n";
#endif
- strUsage += " -txindex " + _("Maintain a full transaction index (default: 0)") + "\n";
+ strUsage += " -txindex " + _("Maintain a full transaction index, used by the getrawtransaction rpc call (default: 0)") + "\n";
strUsage += "\n" + _("Connection options:") + "\n";
strUsage += " -addnode=<ip> " + _("Add a node to connect to and attempt to keep the connection open") + "\n";
@@ -280,7 +280,6 @@ std::string HelpMessage(HelpMessageMode mode)
strUsage += " -mintxfee=<amt> " + strprintf(_("Fees (in BTC/Kb) smaller than this are considered zero fee for transaction creation (default: %s)"), FormatMoney(CWallet::minTxFee.GetFeePerK())) + "\n";
strUsage += " -paytxfee=<amt> " + strprintf(_("Fee (in BTC/kB) to add to transactions you send (default: %s)"), FormatMoney(payTxFee.GetFeePerK())) + "\n";
strUsage += " -rescan " + _("Rescan the block chain for missing wallet transactions") + " " + _("on startup") + "\n";
- strUsage += " -respendnotify=<cmd> " + _("Execute command when a network tx respends wallet tx input (%s=respend TxID, %t=wallet TxID)") + "\n";
strUsage += " -salvagewallet " + _("Attempt to recover private keys from a corrupt wallet.dat") + " " + _("on startup") + "\n";
strUsage += " -spendzeroconfchange " + _("Spend unconfirmed change when sending transactions (default: 1)") + "\n";
strUsage += " -txconfirmtarget=<n> " + _("If paytxfee is not set, include enough fee so transactions are confirmed on average within n blocks (default: 1)") + "\n";
diff --git a/src/main.cpp b/src/main.cpp
index 83848bf84..5d46c30a9 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -26,8 +26,8 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/thread.hpp>
-using namespace std;
using namespace boost;
+using namespace std;
#if defined(NDEBUG)
# error "Bitcoin cannot be compiled without assertions."
@@ -645,7 +645,7 @@ bool AreInputsStandard(const CTransaction& tx, const CCoinsViewCache& mapInputs)
// IsStandard() will have already returned false
// and this method isn't called.
vector<vector<unsigned char> > stack;
- if (!EvalScript(stack, tx.vin[i].scriptSig, tx, i, false))
+ if (!EvalScript(stack, tx.vin[i].scriptSig, false, BaseSignatureChecker()))
return false;
if (whichType == TX_SCRIPTHASH)
@@ -943,7 +943,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa
// Check against previous transactions
// This is done last to help prevent CPU exhaustion denial-of-service attacks.
- if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS))
+ if (!CheckInputs(tx, state, view, true, STANDARD_SCRIPT_VERIFY_FLAGS, true))
{
return error("AcceptToMemoryPool: : ConnectInputs failed %s", hash.ToString());
}
@@ -1316,12 +1316,12 @@ void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCach
bool CScriptCheck::operator()() const {
const CScript &scriptSig = ptxTo->vin[nIn].scriptSig;
- if (!VerifyScript(scriptSig, scriptPubKey, *ptxTo, nIn, nFlags))
+ if (!VerifyScript(scriptSig, scriptPubKey, nFlags, CachingSignatureChecker(*ptxTo, nIn, cacheStore)))
return error("CScriptCheck() : %s:%d VerifySignature failed", ptxTo->GetHash().ToString(), nIn);
return true;
}
-bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, std::vector<CScriptCheck> *pvChecks)
+bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &inputs, bool fScriptChecks, unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks)
{
if (!tx.IsCoinBase())
{
@@ -1390,7 +1390,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
assert(coins);
// Verify signature
- CScriptCheck check(*coins, tx, i, flags);
+ CScriptCheck check(*coins, tx, i, flags, cacheStore);
if (pvChecks) {
pvChecks->push_back(CScriptCheck());
check.swap(pvChecks->back());
@@ -1403,7 +1403,7 @@ bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsVi
// avoid splitting the network between upgraded and
// non-upgraded nodes.
CScriptCheck check(*coins, tx, i,
- flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS);
+ flags & ~STANDARD_NOT_MANDATORY_VERIFY_FLAGS, cacheStore);
if (check())
return state.Invalid(false, REJECT_NONSTANDARD, "non-mandatory-script-verify-flag");
}
@@ -1599,8 +1599,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
int64_t nBIP16SwitchTime = 1333238400;
bool fStrictPayToScriptHash = (pindex->GetBlockTime() >= nBIP16SwitchTime);
- unsigned int flags = SCRIPT_VERIFY_NOCACHE |
- (fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE);
+ unsigned int flags = fStrictPayToScriptHash ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE;
CBlockUndo blockundo;
@@ -1644,7 +1643,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
nFees += view.GetValueIn(tx)-tx.GetValueOut();
std::vector<CScriptCheck> vChecks;
- if (!CheckInputs(tx, state, view, fScriptChecks, flags, nScriptCheckThreads ? &vChecks : NULL))
+ if (!CheckInputs(tx, state, view, fScriptChecks, flags, false, nScriptCheckThreads ? &vChecks : NULL))
return false;
control.Add(vChecks);
}
@@ -1688,7 +1687,7 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
if (!FindUndoPos(state, pindex->nFile, pos, ::GetSerializeSize(blockundo, SER_DISK, CLIENT_VERSION) + 40))
return error("ConnectBlock() : FindUndoPos failed");
if (!blockundo.WriteToDisk(pos, pindex->pprev->GetBlockHash()))
- return state.Abort(_("Failed to write undo data"));
+ return state.Abort("Failed to write undo data");
// update nUndoPos in block index
pindex->nUndoPos = pos.nPos;
@@ -1699,12 +1698,12 @@ bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, C
CDiskBlockIndex blockindex(pindex);
if (!pblocktree->WriteBlockIndex(blockindex))
- return state.Abort(_("Failed to write block index"));
+ return state.Abort("Failed to write block index");
}
if (fTxIndex)
if (!pblocktree->WriteTxIndex(vPos))
- return state.Abort(_("Failed to write transaction index"));
+ return state.Abort("Failed to write transaction index");
// add this block to the view's block chain
bool ret;
@@ -1739,7 +1738,7 @@ bool static WriteChainState(CValidationState &state) {
FlushBlockFile();
pblocktree->Sync();
if (!pcoinsTip->Flush())
- return state.Abort(_("Failed to write to coin database"));
+ return state.Abort("Failed to write to coin database");
nLastWrite = GetTimeMicros();
}
return true;
@@ -1787,7 +1786,7 @@ bool static DisconnectTip(CValidationState &state) {
// Read block from disk.
CBlock block;
if (!ReadBlockFromDisk(block, pindexDelete))
- return state.Abort(_("Failed to read block"));
+ return state.Abort("Failed to read block");
// Apply the block atomically to the chain state.
int64_t nStart = GetTimeMicros();
{
@@ -1836,7 +1835,7 @@ bool static ConnectTip(CValidationState &state, CBlockIndex *pindexNew, CBlock *
CBlock block;
if (!pblock) {
if (!ReadBlockFromDisk(block, pindexNew))
- return state.Abort(_("Failed to read block"));
+ return state.Abort("Failed to read block");
pblock = &block;
}
// Apply the block atomically to the chain state.
@@ -1990,7 +1989,7 @@ static bool ActivateBestChainStep(CValidationState &state, CBlockIndex *pindexMo
CheckForkWarningConditions();
if (!pblocktree->Flush())
- return state.Abort(_("Failed to sync block index"));
+ return state.Abort("Failed to sync block index");
return true;
}
@@ -2027,10 +2026,10 @@ bool ActivateBestChain(CValidationState &state, CBlock *pblock) {
// Relay inventory, but don't relay old inventory during initial block download.
int nBlockEstimate = Checkpoints::GetTotalBlocksEstimate();
{
- LOCK(cs_vNodes);
- BOOST_FOREACH(CNode* pnode, vNodes)
- if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
- pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
+ LOCK(cs_vNodes);
+ BOOST_FOREACH(CNode* pnode, vNodes)
+ if (chainActive.Height() > (pnode->nStartingHeight != -1 ? pnode->nStartingHeight - 2000 : nBlockEstimate))
+ pnode->PushInventory(CInv(MSG_BLOCK, hashNewTip));
}
uiInterface.NotifyBlockTip(hashNewTip);
@@ -2097,7 +2096,7 @@ bool ReceivedBlockTransactions(const CBlock &block, CValidationState& state, CBl
setBlockIndexValid.insert(pindexNew);
if (!pblocktree->WriteBlockIndex(CDiskBlockIndex(pindexNew)))
- return state.Abort(_("Failed to write block index"));
+ return state.Abort("Failed to write block index");
return true;
}
@@ -2149,7 +2148,7 @@ bool FindBlockPos(CValidationState &state, CDiskBlockPos &pos, unsigned int nAdd
}
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
- return state.Abort(_("Failed to write file info"));
+ return state.Abort("Failed to write file info");
if (fUpdatedLast)
pblocktree->WriteLastBlockFile(nLastBlockFile);
@@ -2167,15 +2166,15 @@ bool FindUndoPos(CValidationState &state, int nFile, CDiskBlockPos &pos, unsigne
pos.nPos = infoLastBlockFile.nUndoSize;
nNewSize = (infoLastBlockFile.nUndoSize += nAddSize);
if (!pblocktree->WriteBlockFileInfo(nLastBlockFile, infoLastBlockFile))
- return state.Abort(_("Failed to write block info"));
+ return state.Abort("Failed to write block info");
} else {
CBlockFileInfo info;
if (!pblocktree->ReadBlockFileInfo(nFile, info))
- return state.Abort(_("Failed to read block info"));
+ return state.Abort("Failed to read block info");
pos.nPos = info.nUndoSize;
nNewSize = (info.nUndoSize += nAddSize);
if (!pblocktree->WriteBlockFileInfo(nFile, info))
- return state.Abort(_("Failed to write block info"));
+ return state.Abort("Failed to write block info");
}
unsigned int nOldChunks = (pos.nPos + UNDOFILE_CHUNK_SIZE - 1) / UNDOFILE_CHUNK_SIZE;
@@ -2392,11 +2391,11 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex,
return error("AcceptBlock() : FindBlockPos failed");
if (dbp == NULL)
if (!WriteBlockToDisk(block, blockPos))
- return state.Abort(_("Failed to write block"));
+ return state.Abort("Failed to write block");
if (!ReceivedBlockTransactions(block, state, pindex, blockPos))
return error("AcceptBlock() : ReceivedBlockTransactions failed");
} catch(std::runtime_error &e) {
- return state.Abort(_("System error: ") + e.what());
+ return state.Abort(std::string("System error: ") + e.what());
}
return true;
@@ -2719,10 +2718,12 @@ uint256 CPartialMerkleTree::ExtractMatches(std::vector<uint256> &vMatch) {
-bool AbortNode(const std::string &strMessage) {
+bool AbortNode(const std::string &strMessage, const std::string &userMessage) {
strMiscWarning = strMessage;
LogPrintf("*** %s\n", strMessage);
- uiInterface.ThreadSafeMessageBox(strMessage, "", CClientUIInterface::MSG_ERROR);
+ uiInterface.ThreadSafeMessageBox(
+ userMessage.empty() ? _("Error: A fatal internal error occured, see debug.log for details") : userMessage,
+ "", CClientUIInterface::MSG_ERROR);
StartShutdown();
return false;
}
@@ -2733,7 +2734,7 @@ bool CheckDiskSpace(uint64_t nAdditionalBytes)
// Check for nMinDiskSpace bytes (currently 50MB)
if (nFreeBytesAvailable < nMinDiskSpace + nAdditionalBytes)
- return AbortNode(_("Error: Disk space is low!"));
+ return AbortNode("Disk space is low!", _("Error: Disk space is low!"));
return true;
}
@@ -3143,7 +3144,7 @@ bool LoadExternalBlockFile(FILE* fileIn, CDiskBlockPos *dbp)
}
}
} catch(std::runtime_error &e) {
- AbortNode(_("Error: system error: ") + e.what());
+ AbortNode(std::string("System error: ") + e.what());
}
if (nLoaded > 0)
LogPrintf("Loaded %i blocks from external file in %dms\n", nLoaded, GetTimeMillis() - nStart);
diff --git a/src/main.h b/src/main.h
index 7e849505d..cad7eebfb 100644
--- a/src/main.h
+++ b/src/main.h
@@ -17,6 +17,7 @@
#include "net.h"
#include "pow.h"
#include "script/script.h"
+#include "script/sigcache.h"
#include "script/standard.h"
#include "sync.h"
#include "txmempool.h"
@@ -177,7 +178,7 @@ CAmount GetBlockValue(int nHeight, const CAmount& nFees);
/** Create a new block index entry for a given block hash */
CBlockIndex * InsertBlockIndex(uint256 hash);
/** Abort with a message */
-bool AbortNode(const std::string &msg);
+bool AbortNode(const std::string &msg, const std::string &userMessage="");
/** Get statistics from node state */
bool GetNodeStateStats(NodeId nodeid, CNodeStateStats &stats);
/** Increase a node's misbehavior score. */
@@ -258,9 +259,8 @@ unsigned int GetP2SHSigOpCount(const CTransaction& tx, const CCoinsViewCache& ma
// Check whether all inputs of this transaction are valid (no double spends, scripts & sigs, amounts)
// This does not modify the UTXO set. If pvChecks is not NULL, script checks are pushed onto it
// instead of being performed inline.
-bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks = true,
- unsigned int flags = STANDARD_SCRIPT_VERIFY_FLAGS,
- std::vector<CScriptCheck> *pvChecks = NULL);
+bool CheckInputs(const CTransaction& tx, CValidationState &state, const CCoinsViewCache &view, bool fScriptChecks,
+ unsigned int flags, bool cacheStore, std::vector<CScriptCheck> *pvChecks = NULL);
// Apply the effects of this transaction on the UTXO set represented by view
void UpdateCoins(const CTransaction& tx, CValidationState &state, CCoinsViewCache &inputs, CTxUndo &txundo, int nHeight);
@@ -302,12 +302,13 @@ private:
const CTransaction *ptxTo;
unsigned int nIn;
unsigned int nFlags;
+ bool cacheStore;
public:
- CScriptCheck(): ptxTo(0), nIn(0), nFlags(0) {}
- CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn) :
+ CScriptCheck(): ptxTo(0), nIn(0), nFlags(0), cacheStore(false) {}
+ CScriptCheck(const CCoins& txFromIn, const CTransaction& txToIn, unsigned int nInIn, unsigned int nFlagsIn, bool cacheIn) :
scriptPubKey(txFromIn.vout[txToIn.vin[nInIn].prevout.n].scriptPubKey),
- ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn) { }
+ ptxTo(&txToIn), nIn(nInIn), nFlags(nFlagsIn), cacheStore(cacheIn) { }
bool operator()() const;
@@ -316,6 +317,7 @@ public:
std::swap(ptxTo, check.ptxTo);
std::swap(nIn, check.nIn);
std::swap(nFlags, check.nFlags);
+ std::swap(cacheStore, check.cacheStore);
}
};
diff --git a/src/miner.cpp b/src/miner.cpp
index 361a2bea4..280349e8c 100644
--- a/src/miner.cpp
+++ b/src/miner.cpp
@@ -257,7 +257,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn)
// policy here, but we still have to ensure that the block we
// create only contains transactions that are valid in new blocks.
CValidationState state;
- if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS))
+ if (!CheckInputs(tx, state, view, true, MANDATORY_SCRIPT_VERIFY_FLAGS, true))
continue;
CTxUndo txundo;
diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp
index 3b4b40aae..25c811183 100644
--- a/src/qt/bitcoinstrings.cpp
+++ b/src/qt/bitcoinstrings.cpp
@@ -195,21 +195,11 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet corrupted"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error loading wallet.dat: Wallet requires newer version of Bitcoin Core"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error opening block database"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Error: A fatal internal error occured, see debug.log for details"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Disk space is low!"),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Unsupported argument -tor found, use -onion."),
QT_TRANSLATE_NOOP("bitcoin-core", "Error: Wallet locked, unable to create transaction!"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Error: system error: "),
QT_TRANSLATE_NOOP("bitcoin-core", "Failed to listen on any port. Use -listen=0 if you want this."),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to read block info"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to read block"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to sync block index"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block index"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block info"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write block"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write file info"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write to coin database"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write transaction index"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Failed to write undo data"),
QT_TRANSLATE_NOOP("bitcoin-core", "Fee (in BTC/kB) to add to transactions you send (default: %s)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Force safe mode (default: 0)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Generate coins (default: 0)"),
@@ -231,6 +221,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount for -paytxfee=<amount>: '%s'")
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid amount"),
QT_TRANSLATE_NOOP("bitcoin-core", "Invalid netmask specified in -whitelist: '%s'"),
QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable blocks in memory (default: %u)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Keep at most <n> unconnectable transactions in memory (default: %u)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Limit size of signature cache to <n> entries (default: 50000)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Listen for connections on <port> (default: 8333 or testnet: 18333)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Loading addresses..."),
@@ -245,7 +236,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Need to specify a port with -whitebind: '%s'"
QT_TRANSLATE_NOOP("bitcoin-core", "Node relay options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Not enough file descriptors available."),
QT_TRANSLATE_NOOP("bitcoin-core", "Only accept block chain matching built-in checkpoints (default: 1)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (IPv4, IPv6 or Tor)"),
+QT_TRANSLATE_NOOP("bitcoin-core", "Only connect to nodes in network <net> (ipv4, ipv6 or onion)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Options:"),
QT_TRANSLATE_NOOP("bitcoin-core", "Password for JSON-RPC connections"),
QT_TRANSLATE_NOOP("bitcoin-core", "Prepend debug output with timestamp (default: 1)"),
@@ -282,7 +273,6 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Specify wallet file (within data directory)")
QT_TRANSLATE_NOOP("bitcoin-core", "Specify your own public address"),
QT_TRANSLATE_NOOP("bitcoin-core", "Spend unconfirmed change when sending transactions (default: 1)"),
QT_TRANSLATE_NOOP("bitcoin-core", "Stop running after importing blocks from disk (default: 0)"),
-QT_TRANSLATE_NOOP("bitcoin-core", "System error: "),
QT_TRANSLATE_NOOP("bitcoin-core", "This help message"),
QT_TRANSLATE_NOOP("bitcoin-core", "This is experimental software."),
QT_TRANSLATE_NOOP("bitcoin-core", "This is intended for regression testing tools and app development."),
diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts
index a527602b5..5c3abef2e 100644
--- a/src/qt/locale/bitcoin_en.ts
+++ b/src/qt/locale/bitcoin_en.ts
@@ -19,7 +19,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+14"/>
<source>Copy the currently selected address to the system clipboard</source>
<translation>Copy the currently selected address to the system clipboard</translation>
</message>
@@ -29,7 +29,7 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+58"/>
+ <location line="+67"/>
<source>C&amp;lose</source>
<translation type="unfinished"></translation>
</message>
@@ -39,12 +39,12 @@
<translation>&amp;Copy Address</translation>
</message>
<message>
- <location filename="../forms/addressbookpage.ui" line="-47"/>
+ <location filename="../forms/addressbookpage.ui" line="-53"/>
<source>Delete the currently selected address from the list</source>
<translation>Delete the currently selected address from the list</translation>
</message>
<message>
- <location line="+27"/>
+ <location line="+30"/>
<source>Export the data in the current tab to a file</source>
<translation>Export the data in the current tab to a file</translation>
</message>
@@ -54,7 +54,7 @@
<translation>&amp;Export</translation>
</message>
<message>
- <location line="-27"/>
+ <location line="-30"/>
<source>&amp;Delete</source>
<translation>&amp;Delete</translation>
</message>
@@ -286,17 +286,17 @@
<context>
<name>BitcoinGUI</name>
<message>
- <location filename="../bitcoingui.cpp" line="+300"/>
+ <location filename="../bitcoingui.cpp" line="+327"/>
<source>Sign &amp;message...</source>
<translation>Sign &amp;message...</translation>
</message>
<message>
- <location line="+339"/>
+ <location line="+348"/>
<source>Synchronizing with network...</source>
<translation>Synchronizing with network...</translation>
</message>
<message>
- <location line="-411"/>
+ <location line="-420"/>
<source>&amp;Overview</source>
<translation>&amp;Overview</translation>
</message>
@@ -377,13 +377,13 @@
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+168"/>
+ <location line="+175"/>
<location line="+5"/>
<source>Bitcoin Core client</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+156"/>
+ <location line="+158"/>
<source>Importing blocks from disk...</source>
<translation>Importing blocks from disk...</translation>
</message>
@@ -393,7 +393,7 @@
<translation>Reindexing blocks on disk...</translation>
</message>
<message>
- <location line="-409"/>
+ <location line="-418"/>
<source>Send coins to a Bitcoin address</source>
<translation>Send coins to a Bitcoin address</translation>
</message>
@@ -428,12 +428,12 @@
<translation>&amp;Verify message...</translation>
</message>
<message>
- <location line="+437"/>
+ <location line="+446"/>
<source>Bitcoin</source>
<translation>Bitcoin</translation>
</message>
<message>
- <location line="-655"/>
+ <location line="-664"/>
<source>Wallet</source>
<translation>Wallet</translation>
</message>
@@ -500,12 +500,12 @@
</message>
<message>
<location line="-289"/>
- <location line="+386"/>
+ <location line="+393"/>
<source>[testnet]</source>
<translation>[testnet]</translation>
</message>
<message>
- <location line="-411"/>
+ <location line="-418"/>
<source>Bitcoin Core</source>
<translation type="unfinished">Bitcoin Core</translation>
</message>
@@ -546,7 +546,7 @@
<translation type="unfinished"></translation>
</message>
<message numerus="yes">
- <location line="+310"/>
+ <location line="+316"/>
<source>%n active connection(s) to Bitcoin network</source>
<translation>
<numerusform>%n active connection to Bitcoin network</numerusform>
@@ -554,7 +554,7 @@
</translation>
</message>
<message>
- <location line="+22"/>
+ <location line="+25"/>
<source>No block source available...</source>
<translation>No block source available...</translation>
</message>
@@ -665,7 +665,7 @@ Address: %4
</translation>
</message>
<message>
- <location line="+69"/>
+ <location line="+68"/>
<source>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</source>
<translation>Wallet is &lt;b&gt;encrypted&lt;/b&gt; and currently &lt;b&gt;unlocked&lt;/b&gt;</translation>
</message>
@@ -678,7 +678,7 @@ Address: %4
<context>
<name>ClientModel</name>
<message>
- <location filename="../clientmodel.cpp" line="+138"/>
+ <location filename="../clientmodel.cpp" line="+139"/>
<source>Network Alert</source>
<translation>Network Alert</translation>
</message>
@@ -736,7 +736,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+16"/>
<source>Tree mode</source>
<translation type="unfinished"></translation>
</message>
@@ -1059,7 +1059,7 @@ Address: %4
<context>
<name>HelpMessageDialog</name>
<message>
- <location filename="../utilitydialog.cpp" line="+29"/>
+ <location filename="../utilitydialog.cpp" line="+31"/>
<source>Bitcoin Core</source>
<translation type="unfinished">Bitcoin Core</translation>
</message>
@@ -1201,7 +1201,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+11"/>
+ <location line="+10"/>
<source>Select payment request file</source>
<translation type="unfinished"></translation>
</message>
@@ -1430,12 +1430,12 @@ Address: %4
<translation>&amp;OK</translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+13"/>
<source>&amp;Cancel</source>
<translation>&amp;Cancel</translation>
</message>
<message>
- <location filename="../optionsdialog.cpp" line="+68"/>
+ <location filename="../optionsdialog.cpp" line="+71"/>
<source>default</source>
<translation>default</translation>
</message>
@@ -1479,23 +1479,18 @@ Address: %4
<translation>Form</translation>
</message>
<message>
- <location line="+52"/>
- <location line="+394"/>
+ <location line="+53"/>
+ <location line="+372"/>
<source>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source>
<translation>The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</translation>
</message>
<message>
- <location line="-401"/>
- <source>Wallet</source>
- <translation>Wallet</translation>
- </message>
- <message>
- <location line="+33"/>
+ <location line="-133"/>
<source>Watch-only:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+43"/>
+ <location line="+10"/>
<source>Available:</source>
<translation type="unfinished"></translation>
</message>
@@ -1505,62 +1500,72 @@ Address: %4
<translation>Your current spendable balance</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+41"/>
<source>Pending:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+16"/>
+ <location line="-236"/>
<source>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source>
<translation>Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+112"/>
<source>Immature:</source>
<translation>Immature:</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="-29"/>
<source>Mined balance that has not yet matured</source>
<translation>Mined balance that has not yet matured</translation>
</message>
<message>
- <location line="+23"/>
+ <location line="-163"/>
+ <source>Balances</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+147"/>
<source>Total:</source>
<translation>Total:</translation>
</message>
<message>
- <location line="+16"/>
+ <location line="+61"/>
<source>Your current total balance</source>
<translation>Your current total balance</translation>
</message>
<message>
- <location line="+38"/>
+ <location line="+92"/>
<source>Your current balance in watch-only addresses</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+25"/>
+ <location line="+23"/>
+ <source>Spendable:</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+49"/>
+ <source>Recent transactions</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="-317"/>
<source>Unconfirmed transactions to watch-only addresses</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+25"/>
+ <location line="+50"/>
<source>Mined balance in watch-only addresses that has not yet matured</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+44"/>
+ <location line="+128"/>
<source>Current total balance in watch-only addresses</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+67"/>
- <source>&lt;b&gt;Recent transactions&lt;/b&gt;</source>
- <translation>&lt;b&gt;Recent transactions&lt;/b&gt;</translation>
- </message>
- <message>
- <location filename="../overviewpage.cpp" line="+123"/>
+ <location filename="../overviewpage.cpp" line="+131"/>
<location line="+1"/>
<source>out of sync</source>
<translation>out of sync</translation>
@@ -1569,7 +1574,7 @@ Address: %4
<context>
<name>PaymentServer</name>
<message>
- <location filename="../paymentserver.cpp" line="+405"/>
+ <location filename="../paymentserver.cpp" line="+410"/>
<location line="+14"/>
<location line="+7"/>
<source>URI handling</source>
@@ -1681,7 +1686,7 @@ Address: %4
<context>
<name>PeerTableModel</name>
<message>
- <location filename="../peertablemodel.cpp" line="+112"/>
+ <location filename="../peertablemodel.cpp" line="+118"/>
<source>User Agent</source>
<translation type="unfinished"></translation>
</message>
@@ -1699,17 +1704,17 @@ Address: %4
<context>
<name>QObject</name>
<message>
- <location filename="../bitcoinunits.cpp" line="+200"/>
+ <location filename="../bitcoinunits.cpp" line="+196"/>
<source>Amount</source>
<translation type="unfinished">Amount</translation>
</message>
<message>
- <location filename="../guiutil.cpp" line="+97"/>
+ <location filename="../guiutil.cpp" line="+106"/>
<source>Enter a Bitcoin address (e.g. %1)</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+673"/>
+ <location line="+698"/>
<source>%1 d</source>
<translation type="unfinished"></translation>
</message>
@@ -1795,7 +1800,7 @@ Address: %4
<location line="+23"/>
<location line="+36"/>
<location line="+23"/>
- <location line="+462"/>
+ <location line="+465"/>
<location line="+23"/>
<location line="+23"/>
<location line="+23"/>
@@ -1813,7 +1818,7 @@ Address: %4
<translation>N/A</translation>
</message>
<message>
- <location line="-987"/>
+ <location line="-990"/>
<source>Client version</source>
<translation>Client version</translation>
</message>
@@ -1873,7 +1878,7 @@ Address: %4
<translation>Current number of blocks</translation>
</message>
<message>
- <location line="+300"/>
+ <location line="+303"/>
<source>Received</source>
<translation type="unfinished"></translation>
</message>
@@ -1889,7 +1894,7 @@ Address: %4
</message>
<message>
<location line="+39"/>
- <location filename="../rpcconsole.cpp" line="+234"/>
+ <location filename="../rpcconsole.cpp" line="+236"/>
<location line="+327"/>
<source>Select a peer to view detailed information.</source>
<translation type="unfinished"></translation>
@@ -1965,7 +1970,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-761"/>
+ <location line="-764"/>
<source>Last block time</source>
<translation>Last block time</translation>
</message>
@@ -1990,7 +1995,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+16"/>
<source>Totals</source>
<translation type="unfinished"></translation>
</message>
@@ -2005,7 +2010,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location filename="../forms/rpcconsole.ui" line="-354"/>
+ <location filename="../forms/rpcconsole.ui" line="-357"/>
<source>Build date</source>
<translation>Build date</translation>
</message>
@@ -2163,12 +2168,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+78"/>
+ <location line="+75"/>
<source>Requested payments history</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-98"/>
+ <location line="-95"/>
<source>&amp;Request payment</source>
<translation type="unfinished"></translation>
</message>
@@ -2183,7 +2188,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+14"/>
+ <location line="+17"/>
<source>Remove the selected entries from the list</source>
<translation type="unfinished"></translation>
</message>
@@ -2221,12 +2226,12 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+10"/>
<source>Copy &amp;Address</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+10"/>
<source>&amp;Save Image...</source>
<translation type="unfinished"></translation>
</message>
@@ -2279,7 +2284,7 @@ Address: %4
<context>
<name>RecentRequestsTableModel</name>
<message>
- <location filename="../recentrequeststablemodel.cpp" line="+24"/>
+ <location filename="../recentrequeststablemodel.cpp" line="+26"/>
<source>Date</source>
<translation type="unfinished">Date</translation>
</message>
@@ -2333,7 +2338,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+10"/>
<source>automatically selected</source>
<translation type="unfinished"></translation>
</message>
@@ -2398,22 +2403,22 @@ Address: %4
<translation>Add &amp;Recipient</translation>
</message>
<message>
- <location line="-23"/>
+ <location line="-20"/>
<source>Clear all fields of the form.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-271"/>
+ <location line="-274"/>
<source>Dust:</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+274"/>
+ <location line="+277"/>
<source>Clear &amp;All</source>
<translation>Clear &amp;All</translation>
</message>
<message>
- <location line="+58"/>
+ <location line="+55"/>
<source>Balance:</source>
<translation>Balance:</translation>
</message>
@@ -2653,7 +2658,7 @@ Address: %4
<context>
<name>ShutdownWindow</name>
<message>
- <location filename="../utilitydialog.cpp" line="+51"/>
+ <location filename="../utilitydialog.cpp" line="+47"/>
<source>Bitcoin Core is shutting down...</source>
<translation type="unfinished"></translation>
</message>
@@ -2671,7 +2676,7 @@ Address: %4
<translation>Signatures - Sign / Verify a Message</translation>
</message>
<message>
- <location line="+10"/>
+ <location line="+13"/>
<source>&amp;Sign Message</source>
<translation>&amp;Sign Message</translation>
</message>
@@ -2848,7 +2853,7 @@ Address: %4
<context>
<name>SplashScreen</name>
<message>
- <location filename="../splashscreen.cpp" line="+32"/>
+ <location filename="../splashscreen.cpp" line="+34"/>
<source>Bitcoin Core</source>
<translation type="unfinished">Bitcoin Core</translation>
</message>
@@ -2874,7 +2879,7 @@ Address: %4
<context>
<name>TransactionDesc</name>
<message>
- <location filename="../transactiondesc.cpp" line="+33"/>
+ <location filename="../transactiondesc.cpp" line="+34"/>
<source>Open until %1</source>
<translation>Open until %1</translation>
</message>
@@ -3098,7 +3103,7 @@ Address: %4
<context>
<name>TransactionTableModel</name>
<message>
- <location filename="../transactiontablemodel.cpp" line="+237"/>
+ <location filename="../transactiontablemodel.cpp" line="+235"/>
<source>Date</source>
<translation>Date</translation>
</message>
@@ -3166,7 +3171,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+51"/>
+ <location line="+48"/>
<source>Received with</source>
<translation>Received with</translation>
</message>
@@ -3191,12 +3196,17 @@ Address: %4
<translation>Mined</translation>
</message>
<message>
- <location line="+41"/>
+ <location line="+28"/>
+ <source>watch-only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+15"/>
<source>(n/a)</source>
<translation>(n/a)</translation>
</message>
<message>
- <location line="+193"/>
+ <location line="+210"/>
<source>Transaction status. Hover over this field to show number of confirmations.</source>
<translation>Transaction status. Hover over this field to show number of confirmations.</translation>
</message>
@@ -3212,6 +3222,11 @@ Address: %4
</message>
<message>
<location line="+2"/>
+ <source>Whether or not a watch-only address is involved in this transaction.</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+2"/>
<source>Destination address of transaction.</source>
<translation>Destination address of transaction.</translation>
</message>
@@ -3224,7 +3239,7 @@ Address: %4
<context>
<name>TransactionView</name>
<message>
- <location filename="../transactionview.cpp" line="+60"/>
+ <location filename="../transactionview.cpp" line="+67"/>
<location line="+16"/>
<source>All</source>
<translation>All</translation>
@@ -3325,12 +3340,17 @@ Address: %4
<translation>Show transaction details</translation>
</message>
<message>
- <location line="+163"/>
+ <location line="+179"/>
<source>Export Transaction History</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+19"/>
+ <location line="+12"/>
+ <source>Watch-only</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+9"/>
<source>Exporting Failed</source>
<translation type="unfinished"></translation>
</message>
@@ -3350,7 +3370,7 @@ Address: %4
<translation type="unfinished"></translation>
</message>
<message>
- <location line="-22"/>
+ <location line="-24"/>
<source>Comma separated file (*.csv)</source>
<translation>Comma separated file (*.csv)</translation>
</message>
@@ -3360,7 +3380,7 @@ Address: %4
<translation>Confirmed</translation>
</message>
<message>
- <location line="+1"/>
+ <location line="+3"/>
<source>Date</source>
<translation>Date</translation>
</message>
@@ -3398,7 +3418,7 @@ Address: %4
<context>
<name>UnitDisplayStatusBarControl</name>
<message>
- <location filename="../bitcoingui.cpp" line="+101"/>
+ <location filename="../bitcoingui.cpp" line="+103"/>
<source>Unit to show amounts in. Click to select another unit.</source>
<translation type="unfinished"></translation>
</message>
@@ -3465,7 +3485,7 @@ Address: %4
<context>
<name>bitcoin-core</name>
<message>
- <location filename="../bitcoinstrings.cpp" line="+249"/>
+ <location filename="../bitcoinstrings.cpp" line="+240"/>
<source>Options:</source>
<translation>Options:</translation>
</message>
@@ -3495,22 +3515,22 @@ Address: %4
<translation>Maintain at most &lt;n&gt; connections to peers (default: 125)</translation>
</message>
<message>
- <location line="-62"/>
+ <location line="-53"/>
<source>Connect to a node to retrieve peer addresses, and disconnect</source>
<translation>Connect to a node to retrieve peer addresses, and disconnect</translation>
</message>
<message>
- <location line="+103"/>
+ <location line="+94"/>
<source>Specify your own public address</source>
<translation>Specify your own public address</translation>
</message>
<message>
- <location line="+7"/>
+ <location line="+6"/>
<source>Threshold for disconnecting misbehaving peers (default: 100)</source>
<translation>Threshold for disconnecting misbehaving peers (default: 100)</translation>
</message>
<message>
- <location line="-181"/>
+ <location line="-171"/>
<source>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</source>
<translation>Number of seconds to keep misbehaving peers from reconnecting (default: 86400)</translation>
</message>
@@ -3525,17 +3545,17 @@ Address: %4
<translation>Accept command line and JSON-RPC commands</translation>
</message>
<message>
- <location line="+99"/>
+ <location line="+90"/>
<source>Run in the background as a daemon and accept commands</source>
<translation>Run in the background as a daemon and accept commands</translation>
</message>
<message>
- <location line="+36"/>
+ <location line="+35"/>
<source>Use the test network</source>
<translation>Use the test network</translation>
</message>
<message>
- <location line="-134"/>
+ <location line="-124"/>
<source>Accept connections from outside (default: 1 if no -proxy or -connect)</source>
<translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation>
</message>
@@ -3756,6 +3776,11 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</message>
<message>
<location line="+2"/>
+ <source>Error: A fatal internal error occured, see debug.log for details</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Error: Disk space is low!</source>
<translation>Error: Disk space is low!</translation>
</message>
@@ -3766,65 +3791,10 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</message>
<message>
<location line="+1"/>
- <source>Error: system error: </source>
- <translation>Error: system error: </translation>
- </message>
- <message>
- <location line="+1"/>
<source>Failed to listen on any port. Use -listen=0 if you want this.</source>
<translation>Failed to listen on any port. Use -listen=0 if you want this.</translation>
</message>
<message>
- <location line="+1"/>
- <source>Failed to read block info</source>
- <translation>Failed to read block info</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to read block</source>
- <translation>Failed to read block</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to sync block index</source>
- <translation>Failed to sync block index</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to write block index</source>
- <translation>Failed to write block index</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to write block info</source>
- <translation>Failed to write block info</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to write block</source>
- <translation>Failed to write block</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to write file info</source>
- <translation>Failed to write file info</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to write to coin database</source>
- <translation>Failed to write to coin database</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to write transaction index</source>
- <translation>Failed to write transaction index</translation>
- </message>
- <message>
- <location line="+1"/>
- <source>Failed to write undo data</source>
- <translation>Failed to write undo data</translation>
- </message>
- <message>
<location line="+2"/>
<source>Force safe mode (default: 0)</source>
<translation type="unfinished"></translation>
@@ -3860,12 +3830,17 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+21"/>
+ <location line="+22"/>
<source>Not enough file descriptors available.</source>
<translation>Not enough file descriptors available.</translation>
</message>
<message>
- <location line="+5"/>
+ <location line="+2"/>
+ <source>Only connect to nodes in network &lt;net&gt; (ipv4, ipv6 or onion)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+3"/>
<source>Prepend debug output with timestamp (default: 1)</source>
<translation type="unfinished"></translation>
</message>
@@ -3905,7 +3880,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+3"/>
<source>This is intended for regression testing tools and app development.</source>
<translation type="unfinished"></translation>
</message>
@@ -3940,7 +3915,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Imports blocks from external blk000??.dat file</translation>
</message>
<message>
- <location line="-195"/>
+ <location line="-185"/>
<source>(default: 1, 1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source>
<translation type="unfinished"></translation>
</message>
@@ -4080,12 +4055,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+4"/>
+ <location line="+5"/>
<source>Error: Unsupported argument -tor found, use -onion.</source>
<translation type="unfinished"></translation>
</message>
<message>
- <location line="+14"/>
+ <location line="+3"/>
<source>Fee (in BTC/kB) to add to transactions you send (default: %s)</source>
<translation type="unfinished"></translation>
</message>
@@ -4131,6 +4106,11 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
</message>
<message>
<location line="+1"/>
+ <source>Keep at most &lt;n&gt; unconnectable transactions in memory (default: %u)</source>
+ <translation type="unfinished"></translation>
+ </message>
+ <message>
+ <location line="+1"/>
<source>Limit size of signature cache to &lt;n&gt; entries (default: 50000)</source>
<translation type="unfinished"></translation>
</message>
@@ -4170,12 +4150,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Only accept block chain matching built-in checkpoints (default: 1)</translation>
</message>
<message>
- <location line="+1"/>
- <source>Only connect to nodes in network &lt;net&gt; (IPv4, IPv6 or Tor)</source>
- <translation>Only connect to nodes in network &lt;net&gt; (IPv4, IPv6 or Tor)</translation>
- </message>
- <message>
- <location line="+4"/>
+ <location line="+5"/>
<source>Print block on startup, if found in block index</source>
<translation type="unfinished"></translation>
</message>
@@ -4255,12 +4230,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Specify connection timeout in milliseconds (default: 5000)</translation>
</message>
<message>
- <location line="+7"/>
- <source>System error: </source>
- <translation>System error: </translation>
- </message>
- <message>
- <location line="+2"/>
+ <location line="+8"/>
<source>This is experimental software.</source>
<translation type="unfinished"></translation>
</message>
@@ -4340,22 +4310,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>wallet.dat corrupt, salvage failed</translation>
</message>
<message>
- <location line="-64"/>
+ <location line="-63"/>
<source>Password for JSON-RPC connections</source>
<translation>Password for JSON-RPC connections</translation>
</message>
<message>
- <location line="-164"/>
+ <location line="-155"/>
<source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source>
<translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation>
</message>
<message>
- <location line="+210"/>
+ <location line="+200"/>
<source>Upgrade wallet to latest format</source>
<translation>Upgrade wallet to latest format</translation>
</message>
<message>
- <location line="-27"/>
+ <location line="-26"/>
<source>Set key pool size to &lt;n&gt; (default: 100)</source>
<translation>Set key pool size to &lt;n&gt; (default: 100)</translation>
</message>
@@ -4365,12 +4335,12 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Rescan the block chain for missing wallet transactions</translation>
</message>
<message>
- <location line="+36"/>
+ <location line="+35"/>
<source>Use OpenSSL (https) for JSON-RPC connections</source>
<translation>Use OpenSSL (https) for JSON-RPC connections</translation>
</message>
<message>
- <location line="-31"/>
+ <location line="-30"/>
<source>Server certificate file (default: server.cert)</source>
<translation>Server certificate file (default: server.cert)</translation>
</message>
@@ -4380,22 +4350,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Server private key (default: server.pem)</translation>
</message>
<message>
- <location line="+19"/>
+ <location line="+18"/>
<source>This help message</source>
<translation>This help message</translation>
</message>
<message>
- <location line="-118"/>
+ <location line="-108"/>
<source>Allow DNS lookups for -addnode, -seednode and -connect</source>
<translation>Allow DNS lookups for -addnode, -seednode and -connect</translation>
</message>
<message>
- <location line="+68"/>
+ <location line="+59"/>
<source>Loading addresses...</source>
<translation>Loading addresses...</translation>
</message>
<message>
- <location line="-42"/>
+ <location line="-33"/>
<source>Error loading wallet.dat: Wallet corrupted</source>
<translation>Error loading wallet.dat: Wallet corrupted</translation>
</message>
@@ -4405,7 +4375,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Error loading wallet.dat</translation>
</message>
<message>
- <location line="+33"/>
+ <location line="+23"/>
<source>Invalid -proxy address: &apos;%s&apos;</source>
<translation>Invalid -proxy address: &apos;%s&apos;</translation>
</message>
@@ -4415,7 +4385,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Unknown network specified in -onlynet: &apos;%s&apos;</translation>
</message>
<message>
- <location line="-122"/>
+ <location line="-112"/>
<source>Cannot resolve -bind address: &apos;%s&apos;</source>
<translation>Cannot resolve -bind address: &apos;%s&apos;</translation>
</message>
@@ -4425,7 +4395,7 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Cannot resolve -externalip address: &apos;%s&apos;</translation>
</message>
<message>
- <location line="+56"/>
+ <location line="+46"/>
<source>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</source>
<translation>Invalid amount for -paytxfee=&lt;amount&gt;: &apos;%s&apos;</translation>
</message>
@@ -4440,22 +4410,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Insufficient funds</translation>
</message>
<message>
- <location line="+13"/>
+ <location line="+14"/>
<source>Loading block index...</source>
<translation>Loading block index...</translation>
</message>
<message>
- <location line="-70"/>
+ <location line="-61"/>
<source>Add a node to connect to and attempt to keep the connection open</source>
<translation>Add a node to connect to and attempt to keep the connection open</translation>
</message>
<message>
- <location line="+71"/>
+ <location line="+62"/>
<source>Loading wallet...</source>
<translation>Loading wallet...</translation>
</message>
<message>
- <location line="-66"/>
+ <location line="-57"/>
<source>Cannot downgrade wallet</source>
<translation>Cannot downgrade wallet</translation>
</message>
@@ -4465,22 +4435,22 @@ for example: alertnotify=echo %%s | mail -s &quot;Bitcoin Alert&quot; admin@foo.
<translation>Cannot write default address</translation>
</message>
<message>
- <location line="+86"/>
+ <location line="+77"/>
<source>Rescanning...</source>
<translation>Rescanning...</translation>
</message>
<message>
- <location line="-73"/>
+ <location line="-64"/>
<source>Done loading</source>
<translation>Done loading</translation>
</message>
<message>
- <location line="+101"/>
+ <location line="+91"/>
<source>To use the %s option</source>
<translation>To use the %s option</translation>
</message>
<message>
- <location line="-93"/>
+ <location line="-83"/>
<source>Error</source>
<translation>Error</translation>
</message>
diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp
index bd87d7770..23e647b17 100644
--- a/src/rpcrawtransaction.cpp
+++ b/src/rpcrawtransaction.cpp
@@ -110,6 +110,9 @@ Value getrawtransaction(const Array& params, bool fHelp)
if (fHelp || params.size() < 1 || params.size() > 2)
throw runtime_error(
"getrawtransaction \"txid\" ( verbose )\n"
+ "\nNOTE: By default this function only works sometimes. This is when the tx is in the mempool\n"
+ "or there is an unspent output in the utxo for this transaction. To make it always work,\n"
+ "you need to maintain a transaction index, using the -txindex command line option.\n"
"\nReturn the raw transaction data.\n"
"\nIf verbose=0, returns a string that is serialized, hex-encoded data for 'txid'.\n"
"If verbose is non-zero, returns an Object with information about 'txid'.\n"
@@ -202,7 +205,7 @@ Value listunspent(const Array& params, bool fHelp)
"Results are an array of Objects, each of which has:\n"
"{txid, vout, scriptPubKey, amount, confirmations}\n"
"\nArguments:\n"
- "1. minconf (numeric, optional, default=1) The minimum confirmationsi to filter\n"
+ "1. minconf (numeric, optional, default=1) The minimum confirmations to filter\n"
"2. maxconf (numeric, optional, default=9999999) The maximum confirmations to filter\n"
"3. \"addresses\" (string) A json array of bitcoin addresses to filter\n"
" [\n"
@@ -687,7 +690,7 @@ Value signrawtransaction(const Array& params, bool fHelp)
BOOST_FOREACH(const CMutableTransaction& txv, txVariants) {
txin.scriptSig = CombineSignatures(prevPubKey, mergedTx, i, txin.scriptSig, txv.vin[i].scriptSig);
}
- if (!VerifyScript(txin.scriptSig, prevPubKey, mergedTx, i, STANDARD_SCRIPT_VERIFY_FLAGS))
+ if (!VerifyScript(txin.scriptSig, prevPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(mergedTx, i)))
fComplete = false;
}
diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp
index a71f55dd2..56140f19d 100644
--- a/src/script/interpreter.cpp
+++ b/src/script/interpreter.cpp
@@ -9,14 +9,10 @@
#include "crypto/ripemd160.h"
#include "crypto/sha1.h"
#include "crypto/sha2.h"
-#include "random.h"
#include "script/script.h"
#include "uint256.h"
#include "util.h"
-#include <boost/thread.hpp>
-#include <boost/tuple/tuple_comparison.hpp>
-
using namespace std;
typedef vector<unsigned char> valtype;
@@ -132,7 +128,7 @@ bool IsCanonicalSignature(const valtype &vchSig, unsigned int flags) {
return true;
}
-bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags)
+bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker)
{
CScript::const_iterator pc = script.begin();
CScript::const_iterator pend = script.end();
@@ -675,7 +671,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
scriptCode.FindAndDelete(CScript(vchSig));
bool fSuccess = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) &&
- CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags);
+ checker.CheckSig(vchSig, vchPubKey, scriptCode);
popstack(stack);
popstack(stack);
@@ -736,7 +732,7 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, co
// Check signature
bool fOk = IsCanonicalSignature(vchSig, flags) && IsCanonicalPubKey(vchPubKey, flags) &&
- CheckSig(vchSig, vchPubKey, scriptCode, txTo, nIn, flags);
+ checker.CheckSig(vchSig, vchPubKey, scriptCode);
if (fOk) {
isig++;
@@ -897,7 +893,7 @@ public:
} // anon namespace
-uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
+uint256 SignatureHash(const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType)
{
if (nIn >= txTo.vin.size()) {
LogPrintf("ERROR: SignatureHash() : nIn=%d out of range\n", nIn);
@@ -921,70 +917,19 @@ uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsig
return ss.GetHash();
}
-// Valid signature cache, to avoid doing expensive ECDSA signature checking
-// twice for every transaction (once when accepted into memory pool, and
-// again when accepted into the block chain)
-class CSignatureCache
+bool SignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
{
-private:
- // sigdata_type is (signature hash, signature, public key):
- typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
- std::set< sigdata_type> setValid;
- boost::shared_mutex cs_sigcache;
-
-public:
- bool
- Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
- {
- boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
-
- sigdata_type k(hash, vchSig, pubKey);
- std::set<sigdata_type>::iterator mi = setValid.find(k);
- if (mi != setValid.end())
- return true;
- return false;
- }
-
- void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
- {
- // DoS prevention: limit cache size to less than 10MB
- // (~200 bytes per cache entry times 50,000 entries)
- // Since there are a maximum of 20,000 signature operations per block
- // 50,000 is a reasonable default.
- int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
- if (nMaxCacheSize <= 0) return;
-
- boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
-
- while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize)
- {
- // Evict a random entry. Random because that helps
- // foil would-be DoS attackers who might try to pre-generate
- // and re-use a set of valid signatures just-slightly-greater
- // than our cache size.
- uint256 randomHash = GetRandHash();
- std::vector<unsigned char> unused;
- std::set<sigdata_type>::iterator it =
- setValid.lower_bound(sigdata_type(randomHash, unused, unused));
- if (it == setValid.end())
- it = setValid.begin();
- setValid.erase(*it);
- }
-
- sigdata_type k(hash, vchSig, pubKey);
- setValid.insert(k);
- }
-};
+ return pubkey.Verify(sighash, vchSig);
+}
-bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char>& vchPubKey, const CScript& scriptCode, const CTransaction& txTo, unsigned int nIn, int flags)
+bool SignatureChecker::CheckSig(const vector<unsigned char>& vchSigIn, const vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
{
- static CSignatureCache signatureCache;
-
CPubKey pubkey(vchPubKey);
if (!pubkey.IsValid())
return false;
// Hash type is one byte tacked on to the end of the signature
+ vector<unsigned char> vchSig(vchSigIn);
if (vchSig.empty())
return false;
int nHashType = vchSig.back();
@@ -992,26 +937,20 @@ bool CheckSig(vector<unsigned char> vchSig, const vector<unsigned char>& vchPubK
uint256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
- if (signatureCache.Get(sighash, vchSig, pubkey))
- return true;
-
- if (!pubkey.Verify(sighash, vchSig))
+ if (!VerifySignature(vchSig, pubkey, sighash))
return false;
- if (!(flags & SCRIPT_VERIFY_NOCACHE))
- signatureCache.Set(sighash, vchSig, pubkey);
-
return true;
}
-bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags)
+bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker)
{
vector<vector<unsigned char> > stack, stackCopy;
- if (!EvalScript(stack, scriptSig, txTo, nIn, flags))
+ if (!EvalScript(stack, scriptSig, flags, checker))
return false;
if (flags & SCRIPT_VERIFY_P2SH)
stackCopy = stack;
- if (!EvalScript(stack, scriptPubKey, txTo, nIn, flags))
+ if (!EvalScript(stack, scriptPubKey, flags, checker))
return false;
if (stack.empty())
return false;
@@ -1034,7 +973,7 @@ bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const C
CScript pubKey2(pubKeySerialized.begin(), pubKeySerialized.end());
popstack(stackCopy);
- if (!EvalScript(stackCopy, pubKey2, txTo, nIn, flags))
+ if (!EvalScript(stackCopy, pubKey2, flags, checker))
return false;
if (stackCopy.empty())
return false;
diff --git a/src/script/interpreter.h b/src/script/interpreter.h
index adca2142a..0ff73964b 100644
--- a/src/script/interpreter.h
+++ b/src/script/interpreter.h
@@ -10,6 +10,7 @@
#include <stdint.h>
#include <string>
+class CPubKey;
class CScript;
class CTransaction;
class uint256;
@@ -30,16 +31,40 @@ enum
SCRIPT_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts
SCRIPT_VERIFY_STRICTENC = (1U << 1), // enforce strict conformance to DER and SEC2 for signatures and pubkeys
SCRIPT_VERIFY_LOW_S = (1U << 2), // enforce low S values (<n/2) in signatures (depends on STRICTENC)
- SCRIPT_VERIFY_NOCACHE = (1U << 3), // do not store results in signature cache (but do query it)
- SCRIPT_VERIFY_NULLDUMMY = (1U << 4), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length
+ SCRIPT_VERIFY_NULLDUMMY = (1U << 3), // verify dummy stack item consumed by CHECKMULTISIG is of zero-length
};
bool IsCanonicalPubKey(const std::vector<unsigned char> &vchPubKey, unsigned int flags);
bool IsCanonicalSignature(const std::vector<unsigned char> &vchSig, unsigned int flags);
uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType);
-bool CheckSig(std::vector<unsigned char> vchSig, const std::vector<unsigned char> &vchPubKey, const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int flags);
-bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, const CTransaction& txTo, unsigned int nIn, unsigned int flags);
-bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, const CTransaction& txTo, unsigned int nIn, unsigned int flags);
+
+class BaseSignatureChecker
+{
+public:
+ virtual bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const
+ {
+ return false;
+ }
+
+ virtual ~BaseSignatureChecker() {}
+};
+
+class SignatureChecker : public BaseSignatureChecker
+{
+private:
+ const CTransaction& txTo;
+ unsigned int nIn;
+
+protected:
+ virtual bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
+
+public:
+ SignatureChecker(const CTransaction& txToIn, unsigned int nInIn) : txTo(txToIn), nIn(nInIn) {}
+ bool CheckSig(const std::vector<unsigned char>& scriptSig, const std::vector<unsigned char>& vchPubKey, const CScript& scriptCode) const;
+};
+
+bool EvalScript(std::vector<std::vector<unsigned char> >& stack, const CScript& script, unsigned int flags, const BaseSignatureChecker& checker);
+bool VerifyScript(const CScript& scriptSig, const CScript& scriptPubKey, unsigned int flags, const BaseSignatureChecker& checker);
#endif // H_BITCOIN_SCRIPT_INTERPRETER
diff --git a/src/script/sigcache.cpp b/src/script/sigcache.cpp
new file mode 100644
index 000000000..ab366898d
--- /dev/null
+++ b/src/script/sigcache.cpp
@@ -0,0 +1,88 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "sigcache.h"
+
+#include "key.h"
+#include "random.h"
+#include "uint256.h"
+#include "util.h"
+
+#include <boost/thread.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+
+namespace {
+
+// Valid signature cache, to avoid doing expensive ECDSA signature checking
+// twice for every transaction (once when accepted into memory pool, and
+// again when accepted into the block chain)
+class CSignatureCache
+{
+private:
+ // sigdata_type is (signature hash, signature, public key):
+ typedef boost::tuple<uint256, std::vector<unsigned char>, CPubKey> sigdata_type;
+ std::set< sigdata_type> setValid;
+ boost::shared_mutex cs_sigcache;
+
+public:
+ bool
+ Get(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
+ {
+ boost::shared_lock<boost::shared_mutex> lock(cs_sigcache);
+
+ sigdata_type k(hash, vchSig, pubKey);
+ std::set<sigdata_type>::iterator mi = setValid.find(k);
+ if (mi != setValid.end())
+ return true;
+ return false;
+ }
+
+ void Set(const uint256 &hash, const std::vector<unsigned char>& vchSig, const CPubKey& pubKey)
+ {
+ // DoS prevention: limit cache size to less than 10MB
+ // (~200 bytes per cache entry times 50,000 entries)
+ // Since there are a maximum of 20,000 signature operations per block
+ // 50,000 is a reasonable default.
+ int64_t nMaxCacheSize = GetArg("-maxsigcachesize", 50000);
+ if (nMaxCacheSize <= 0) return;
+
+ boost::unique_lock<boost::shared_mutex> lock(cs_sigcache);
+
+ while (static_cast<int64_t>(setValid.size()) > nMaxCacheSize)
+ {
+ // Evict a random entry. Random because that helps
+ // foil would-be DoS attackers who might try to pre-generate
+ // and re-use a set of valid signatures just-slightly-greater
+ // than our cache size.
+ uint256 randomHash = GetRandHash();
+ std::vector<unsigned char> unused;
+ std::set<sigdata_type>::iterator it =
+ setValid.lower_bound(sigdata_type(randomHash, unused, unused));
+ if (it == setValid.end())
+ it = setValid.begin();
+ setValid.erase(*it);
+ }
+
+ sigdata_type k(hash, vchSig, pubKey);
+ setValid.insert(k);
+ }
+};
+
+}
+
+bool CachingSignatureChecker::VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& pubkey, const uint256& sighash) const
+{
+ static CSignatureCache signatureCache;
+
+ if (signatureCache.Get(sighash, vchSig, pubkey))
+ return true;
+
+ if (!SignatureChecker::VerifySignature(vchSig, pubkey, sighash))
+ return false;
+
+ if (store)
+ signatureCache.Set(sighash, vchSig, pubkey);
+ return true;
+}
diff --git a/src/script/sigcache.h b/src/script/sigcache.h
new file mode 100644
index 000000000..46b8f4d33
--- /dev/null
+++ b/src/script/sigcache.h
@@ -0,0 +1,26 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2014 The Bitcoin developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef H_BITCOIN_SCRIPT_SIGCACHE
+#define H_BITCOIN_SCRIPT_SIGCACHE
+
+#include "script/interpreter.h"
+
+#include <vector>
+
+class CPubKey;
+
+class CachingSignatureChecker : public SignatureChecker
+{
+private:
+ bool store;
+
+public:
+ CachingSignatureChecker(const CTransaction& txToIn, unsigned int nInIn, bool storeIn=true) : SignatureChecker(txToIn, nInIn), store(storeIn) {}
+
+ bool VerifySignature(const std::vector<unsigned char>& vchSig, const CPubKey& vchPubKey, const uint256& sighash) const;
+};
+
+#endif // H_BITCOIN_SCRIPT_SIGCACHE
diff --git a/src/script/sign.cpp b/src/script/sign.cpp
index 8abd8d221..da77e7d1f 100644
--- a/src/script/sign.cpp
+++ b/src/script/sign.cpp
@@ -123,7 +123,7 @@ bool SignSignature(const CKeyStore &keystore, const CScript& fromPubKey, CMutabl
}
// Test solution
- return VerifyScript(txin.scriptSig, fromPubKey, txTo, nIn, STANDARD_SCRIPT_VERIFY_FLAGS);
+ return VerifyScript(txin.scriptSig, fromPubKey, STANDARD_SCRIPT_VERIFY_FLAGS, SignatureChecker(txTo, nIn));
}
bool SignSignature(const CKeyStore &keystore, const CTransaction& txFrom, CMutableTransaction& txTo, unsigned int nIn, int nHashType)
@@ -174,7 +174,7 @@ static CScript CombineMultisig(CScript scriptPubKey, const CMutableTransaction&
if (sigs.count(pubkey))
continue; // Already got a sig for this pubkey
- if (CheckSig(sig, pubkey, scriptPubKey, txTo, nIn, 0))
+ if (SignatureChecker(txTo, nIn).CheckSig(sig, pubkey, scriptPubKey))
{
sigs[pubkey] = sig;
break;
@@ -252,9 +252,9 @@ CScript CombineSignatures(CScript scriptPubKey, const CTransaction& txTo, unsign
Solver(scriptPubKey, txType, vSolutions);
vector<valtype> stack1;
- EvalScript(stack1, scriptSig1, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC);
+ EvalScript(stack1, scriptSig1, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
vector<valtype> stack2;
- EvalScript(stack2, scriptSig2, CTransaction(), 0, SCRIPT_VERIFY_STRICTENC);
+ EvalScript(stack2, scriptSig2, SCRIPT_VERIFY_STRICTENC, BaseSignatureChecker());
return CombineSignatures(scriptPubKey, txTo, nIn, txType, vSolutions, stack1, stack2);
}
diff --git a/src/script/standard.cpp b/src/script/standard.cpp
index 407baf621..53ae254d5 100644
--- a/src/script/standard.cpp
+++ b/src/script/standard.cpp
@@ -203,7 +203,11 @@ bool ExtractDestination(const CScript& scriptPubKey, CTxDestination& addressRet)
if (whichType == TX_PUBKEY)
{
- addressRet = CPubKey(vSolutions[0]).GetID();
+ CPubKey pubKey(vSolutions[0]);
+ if (!pubKey.IsValid())
+ return false;
+
+ addressRet = pubKey.GetID();
return true;
}
else if (whichType == TX_PUBKEYHASH)
@@ -237,9 +241,16 @@ bool ExtractDestinations(const CScript& scriptPubKey, txnouttype& typeRet, vecto
nRequiredRet = vSolutions.front()[0];
for (unsigned int i = 1; i < vSolutions.size()-1; i++)
{
- CTxDestination address = CPubKey(vSolutions[i]).GetID();
+ CPubKey pubKey(vSolutions[i]);
+ if (!pubKey.IsValid())
+ continue;
+
+ CTxDestination address = pubKey.GetID();
addressRet.push_back(address);
}
+
+ if (addressRet.empty())
+ return false;
}
else
{
diff --git a/src/test/multisig_tests.cpp b/src/test/multisig_tests.cpp
index cb3774006..5a2ec1cb3 100644
--- a/src/test/multisig_tests.cpp
+++ b/src/test/multisig_tests.cpp
@@ -82,19 +82,19 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
keys.clear();
keys += key[0],key[1]; // magic operator+= from boost.assign
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK(VerifyScript(s, a_and_b, txTo[0], 0, flags));
+ BOOST_CHECK(VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0)));
for (int i = 0; i < 4; i++)
{
keys.clear();
keys += key[i];
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 1: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0)), strprintf("a&b 1: %d", i));
keys.clear();
keys += key[1],key[i];
s = sign_multisig(a_and_b, keys, txTo[0], 0);
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, txTo[0], 0, flags), strprintf("a&b 2: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_and_b, flags, SignatureChecker(txTo[0], 0)), strprintf("a&b 2: %d", i));
}
// Test a OR b:
@@ -104,16 +104,16 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
keys += key[i];
s = sign_multisig(a_or_b, keys, txTo[1], 0);
if (i == 0 || i == 1)
- BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0)), strprintf("a|b: %d", i));
else
- BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, txTo[1], 0, flags), strprintf("a|b: %d", i));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0)), strprintf("a|b: %d", i));
}
s.clear();
s << OP_0 << OP_0;
- BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags));
+ BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0)));
s.clear();
s << OP_0 << OP_1;
- BOOST_CHECK(!VerifyScript(s, a_or_b, txTo[1], 0, flags));
+ BOOST_CHECK(!VerifyScript(s, a_or_b, flags, SignatureChecker(txTo[1], 0)));
for (int i = 0; i < 4; i++)
@@ -123,9 +123,9 @@ BOOST_AUTO_TEST_CASE(multisig_verify)
keys += key[i],key[j];
s = sign_multisig(escrow, keys, txTo[2], 0);
if (i < j && i < 3 && j < 3)
- BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 1: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0)), strprintf("escrow 1: %d %d", i, j));
else
- BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, txTo[2], 0, flags), strprintf("escrow 2: %d %d", i, j));
+ BOOST_CHECK_MESSAGE(!VerifyScript(s, escrow, flags, SignatureChecker(txTo[2], 0)), strprintf("escrow 2: %d %d", i, j));
}
}
diff --git a/src/test/script_P2SH_tests.cpp b/src/test/script_P2SH_tests.cpp
index e6cf00c2d..6c32a263a 100644
--- a/src/test/script_P2SH_tests.cpp
+++ b/src/test/script_P2SH_tests.cpp
@@ -42,7 +42,7 @@ Verify(const CScript& scriptSig, const CScript& scriptPubKey, bool fStrict)
txTo.vin[0].scriptSig = scriptSig;
txTo.vout[0].nValue = 1;
- return VerifyScript(scriptSig, scriptPubKey, txTo, 0, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE);
+ return VerifyScript(scriptSig, scriptPubKey, fStrict ? SCRIPT_VERIFY_P2SH : SCRIPT_VERIFY_NONE, SignatureChecker(txTo, 0));
}
@@ -113,7 +113,7 @@ BOOST_AUTO_TEST_CASE(sign)
{
CScript sigSave = txTo[i].vin[0].scriptSig;
txTo[i].vin[0].scriptSig = txTo[j].vin[0].scriptSig;
- bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC)();
+ bool sigOK = CScriptCheck(CCoins(txFrom, 0), txTo[i], 0, SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC, false)();
if (i == j)
BOOST_CHECK_MESSAGE(sigOK, strprintf("VerifySignature %d %d", i, j));
else
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 48a5635d8..6ed3e03f5 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -89,7 +89,7 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu
void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message)
{
- BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0, flags) == expect, message);
+ BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0)) == expect, message);
}
namespace
@@ -464,18 +464,18 @@ BOOST_AUTO_TEST_CASE(script_PushData)
static const unsigned char pushdata4[] = { OP_PUSHDATA4, 1, 0, 0, 0, 0x5a };
vector<vector<unsigned char> > directStack;
- BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), CTransaction(), 0, true));
+ BOOST_CHECK(EvalScript(directStack, CScript(&direct[0], &direct[sizeof(direct)]), true, BaseSignatureChecker()));
vector<vector<unsigned char> > pushdata1Stack;
- BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), CTransaction(), 0, true));
+ BOOST_CHECK(EvalScript(pushdata1Stack, CScript(&pushdata1[0], &pushdata1[sizeof(pushdata1)]), true, BaseSignatureChecker()));
BOOST_CHECK(pushdata1Stack == directStack);
vector<vector<unsigned char> > pushdata2Stack;
- BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), CTransaction(), 0, true));
+ BOOST_CHECK(EvalScript(pushdata2Stack, CScript(&pushdata2[0], &pushdata2[sizeof(pushdata2)]), true, BaseSignatureChecker()));
BOOST_CHECK(pushdata2Stack == directStack);
vector<vector<unsigned char> > pushdata4Stack;
- BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), CTransaction(), 0, true));
+ BOOST_CHECK(EvalScript(pushdata4Stack, CScript(&pushdata4[0], &pushdata4[sizeof(pushdata4)]), true, BaseSignatureChecker()));
BOOST_CHECK(pushdata4Stack == directStack);
}
@@ -525,15 +525,15 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12)
CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12);
CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0)));
txTo12.vout[0].nValue = 2;
- BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, txTo12, 0, flags));
+ BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0)));
CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, txTo12, 0, flags));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, SignatureChecker(txTo12, 0)));
CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, txTo12, 0, flags));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, SignatureChecker(txTo12, 0)));
}
BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
@@ -553,46 +553,46 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23)
std::vector<CKey> keys;
keys.push_back(key1); keys.push_back(key2);
CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear();
keys.push_back(key1); keys.push_back(key3);
CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear();
keys.push_back(key2); keys.push_back(key3);
CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear();
keys.push_back(key2); keys.push_back(key2); // Can't re-use sig
CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear();
keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order
CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear();
keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order
CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear();
keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys
CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear();
keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys
CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
keys.clear(); // Must have signatures
CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23);
- BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, txTo23, 0, flags));
+ BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, SignatureChecker(txTo23, 0)));
}
BOOST_AUTO_TEST_CASE(script_combineSigs)
diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp
index 83116b51e..823afa168 100644
--- a/src/test/transaction_tests.cpp
+++ b/src/test/transaction_tests.cpp
@@ -27,7 +27,6 @@ using namespace boost::algorithm;
// In script_tests.cpp
extern Array read_json(const std::string& jsondata);
-// Note how NOCACHE is not included as it is a runtime-only flag.
static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of
(string("NONE"), (unsigned int)SCRIPT_VERIFY_NONE)
(string("P2SH"), (unsigned int)SCRIPT_VERIFY_P2SH)
@@ -139,7 +138,7 @@ BOOST_AUTO_TEST_CASE(tx_valid)
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
BOOST_CHECK_MESSAGE(VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- tx, i, verify_flags),
+ verify_flags, SignatureChecker(tx, i)),
strTest);
}
}
@@ -212,7 +211,7 @@ BOOST_AUTO_TEST_CASE(tx_invalid)
unsigned int verify_flags = ParseScriptFlags(test[2].get_str());
fValid = VerifyScript(tx.vin[i].scriptSig, mapprevOutScriptPubKeys[tx.vin[i].prevout],
- tx, i, verify_flags);
+ verify_flags, SignatureChecker(tx, i));
}
BOOST_CHECK_MESSAGE(!fValid, strTest);