aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml15
-rw-r--r--configure.ac55
-rw-r--r--contrib/debian/bitcoind.manpages1
-rw-r--r--contrib/debian/changelog12
-rw-r--r--contrib/debian/control2
-rw-r--r--contrib/debian/manpages/bitcoin-cli.148
-rw-r--r--contrib/gitian-descriptors/gitian-linux.yml13
-rw-r--r--contrib/gitian-descriptors/gitian-osx.yml4
-rw-r--r--contrib/gitian-descriptors/gitian-win.yml4
-rw-r--r--contrib/gitian-downloader/fanquake-key.pgp63
-rw-r--r--contrib/gitian-downloader/jonasschnelli-key.pgpbin0 -> 2230 bytes
-rw-r--r--contrib/gitian-downloader/jonasschnelli.pgpbin4460 -> 0 bytes
-rw-r--r--depends/Makefile1
-rw-r--r--depends/README.usage1
-rw-r--r--depends/packages/packages.mk7
-rw-r--r--doc/REST-interface.md14
-rw-r--r--doc/bips.md18
-rw-r--r--doc/release-process.md1
-rw-r--r--doc/unit-tests.md2
-rwxr-xr-xqa/rpc-tests/rest.py9
-rw-r--r--src/Makefile.am9
-rw-r--r--src/Makefile.test.include1
-rw-r--r--src/allocators.h10
-rw-r--r--src/arith_uint256.cpp9
-rw-r--r--src/base58.cpp2
-rw-r--r--src/bitcoind.cpp16
-rw-r--r--src/chain.h6
-rw-r--r--src/chainparams.h8
-rw-r--r--src/compat/byteswap.h47
-rw-r--r--src/compat/endian.h194
-rw-r--r--src/compat/glibcxx_compat.cpp94
-rw-r--r--src/crypter.cpp4
-rw-r--r--src/crypter.h4
-rw-r--r--src/crypto/common.h76
-rw-r--r--src/db.cpp2
-rw-r--r--src/hash.cpp6
-rw-r--r--src/key.cpp2
-rw-r--r--src/main.cpp112
-rw-r--r--src/net.cpp14
-rw-r--r--src/net.h7
-rw-r--r--src/netbase.h2
-rw-r--r--src/pow.cpp15
-rw-r--r--src/pow.h1
-rw-r--r--src/primitives/block.cpp3
-rw-r--r--src/primitives/transaction.h3
-rw-r--r--src/protocol.cpp13
-rw-r--r--src/protocol.h8
-rw-r--r--src/pubkey.cpp33
-rw-r--r--src/qt/bitcoingui.cpp18
-rw-r--r--src/qt/bitcoingui.h6
-rw-r--r--src/qt/clientmodel.cpp29
-rw-r--r--src/qt/clientmodel.h8
-rw-r--r--src/qt/forms/helpmessagedialog.ui82
-rw-r--r--src/qt/forms/sendcoinsdialog.ui20
-rw-r--r--src/qt/guiutil.cpp46
-rw-r--r--src/qt/optionsdialog.cpp2
-rw-r--r--src/qt/paymentrequestplus.cpp1
-rw-r--r--src/qt/paymentrequestplus.h2
-rw-r--r--src/qt/paymentserver.cpp26
-rw-r--r--src/qt/paymentserver.h2
-rw-r--r--src/qt/rpcconsole.cpp9
-rw-r--r--src/qt/rpcconsole.h4
-rw-r--r--src/qt/sendcoinsdialog.cpp2
-rw-r--r--src/qt/test/paymentrequestdata.h25
-rw-r--r--src/qt/test/paymentservertests.cpp17
-rw-r--r--src/qt/utilitydialog.cpp3
-rw-r--r--src/random.cpp13
-rw-r--r--src/rest.cpp33
-rw-r--r--src/rpcmining.cpp2
-rw-r--r--src/rpcmisc.cpp2
-rw-r--r--src/rpcserver.cpp2
-rw-r--r--src/rpcwallet.cpp27
-rw-r--r--src/script/script.h16
-rw-r--r--src/serialize.h201
-rw-r--r--src/streams.h1
-rw-r--r--src/support/cleanse.cpp13
-rw-r--r--src/support/cleanse.h13
-rw-r--r--src/test/data/script_invalid.json8
-rw-r--r--src/test/data/script_valid.json8
-rw-r--r--src/test/pow_tests.cpp66
-rw-r--r--src/test/script_tests.cpp8
-rw-r--r--src/test/serialize_tests.cpp114
-rw-r--r--src/txmempool.cpp4
-rw-r--r--src/util.cpp7
84 files changed, 1252 insertions, 559 deletions
diff --git a/.travis.yml b/.travis.yml
index 3c995be9a5..9c18729b42 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,6 +10,7 @@ env:
global:
- MAKEJOBS=-j3
- RUN_TESTS=false
+ - BOOST_TEST_RANDOM=1$TRAVIS_BUILD_ID
- CCACHE_SIZE=100M
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
@@ -25,19 +26,19 @@ matrix:
fast_finish: true
include:
- compiler: ": ARM"
- env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ env: HOST=arm-linux-gnueabihf PACKAGES="g++-arm-linux-gnueabihf" DEP_OPTS="NO_QT=1" GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
- compiler: ": bitcoind"
- env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat CPPFLAGS=-DDEBUG_LOCKORDER"
+ env: HOST=x86_64-unknown-linux-gnu PACKAGES="bc" DEP_OPTS="NO_QT=1 NO_UPNP=1 DEBUG=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports CPPFLAGS=-DDEBUG_LOCKORDER"
- compiler: ": No wallet"
- env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat"
+ env: HOST=x86_64-unknown-linux-gnu DEP_OPTS="NO_WALLET=1" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
- compiler: ": 32-bit + dash"
- env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat" USE_SHELL="/bin/dash"
+ env: HOST=i686-pc-linux-gnu PACKAGES="g++-multilib bc" RUN_TESTS=true GOAL="install" BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++" USE_SHELL="/bin/dash"
- compiler: ": Cross-Mac"
- env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" OSX_SDK=10.9 GOAL="deploy"
+ env: HOST=x86_64-apple-darwin11 PACKAGES="cmake libcap-dev libz-dev libbz2-dev" BITCOIN_CONFIG="--enable-reduce-exports" OSX_SDK=10.9 GOAL="deploy"
- compiler: ": Win64"
- env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
+ env: HOST=x86_64-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-x86-64 g++-mingw-w64-x86-64 binutils-mingw-w64-x86-64 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
- compiler: ": Win32"
- env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui" MAKEJOBS="-j2"
+ env: HOST=i686-w64-mingw32 PACKAGES="nsis gcc-mingw-w64-i686 g++-mingw-w64-i686 binutils-mingw-w64-i686 mingw-w64-dev wine bc" RUN_TESTS=true GOAL="deploy" BITCOIN_CONFIG="--enable-gui --enable-reduce-exports" MAKEJOBS="-j2"
install:
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get update; fi
- if [ -n "$PACKAGES" ]; then travis_retry sudo apt-get install --no-install-recommends --no-upgrade -qq $PACKAGES; fi
diff --git a/configure.ac b/configure.ac
index 85e3d1d669..2c918218bb 100644
--- a/configure.ac
+++ b/configure.ac
@@ -115,9 +115,9 @@ AC_ARG_ENABLE([hardening],
AC_ARG_ENABLE([reduce-exports],
[AS_HELP_STRING([--enable-reduce-exports],
- [attempt to reduce exported symbols in the resulting executables (default is yes)])],
+ [attempt to reduce exported symbols in the resulting executables (default is no)])],
[use_reduce_exports=$enableval],
- [use_reduce_exports=auto])
+ [use_reduce_exports=no])
AC_ARG_ENABLE([ccache],
[AS_HELP_STRING([--enable-ccache],
@@ -133,7 +133,7 @@ AC_ARG_ENABLE([lcov],
AC_ARG_ENABLE([glibc-back-compat],
[AS_HELP_STRING([--enable-glibc-back-compat],
- [enable backwards compatibility with glibc and libstdc++])],
+ [enable backwards compatibility with glibc])],
[use_glibc_compat=$enableval],
[use_glibc_compat=no])
@@ -350,8 +350,8 @@ if test x$use_lcov = xyes; then
[AC_MSG_ERROR("lcov testing requested but --coverage flag does not work")])
fi
-dnl Require little endian
-AC_C_BIGENDIAN([AC_MSG_ERROR("Big Endian not supported")])
+dnl Check for endianness
+AC_C_BIGENDIAN
dnl Check for pthread compile/link requirements
AX_PTHREAD
@@ -438,17 +438,22 @@ if test x$TARGET_OS = xdarwin; then
AX_CHECK_LINK_FLAG([[-Wl,-dead_strip]], [LDFLAGS="$LDFLAGS -Wl,-dead_strip"])
fi
-AC_CHECK_HEADERS([endian.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
+AC_CHECK_HEADERS([endian.h byteswap.h stdio.h stdlib.h unistd.h strings.h sys/types.h sys/stat.h sys/select.h sys/prctl.h])
AC_SEARCH_LIBS([getaddrinfo_a], [anl], [AC_DEFINE(HAVE_GETADDRINFO_A, 1, [Define this symbol if you have getaddrinfo_a])])
AC_SEARCH_LIBS([inet_pton], [nsl resolv], [AC_DEFINE(HAVE_INET_PTON, 1, [Define this symbol if you have inet_pton])])
AC_CHECK_DECLS([strnlen])
-AC_CHECK_DECLS([le32toh, le64toh, htole32, htole64, be32toh, be64toh, htobe32, htobe64],,,
+AC_CHECK_DECLS([le16toh, le32toh, le64toh, htole16, htole32, htole64, be16toh, be32toh, be64toh, htobe16, htobe32, htobe64],,,
[#if HAVE_ENDIAN_H
#include <endian.h>
#endif])
+AC_CHECK_DECLS([bswap_16, bswap_32, bswap_64],,,
+ [#if HAVE_BYTESWAP_H
+ #include <byteswap.h>
+ #endif])
+
dnl Check for MSG_NOSIGNAL
AC_MSG_CHECKING(for MSG_NOSIGNAL)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/socket.h>]],
@@ -471,22 +476,14 @@ AC_LINK_IFELSE([AC_LANG_SOURCE([
[
AC_MSG_RESULT(no)
if test x$use_reduce_exports = xyes; then
- AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduced-exports.])
+ AC_MSG_ERROR([Cannot find a working visibility attribute. Use --disable-reduce-exports.])
fi
- AC_MSG_WARN([Cannot find a working visibility attribute. Disabling reduced exports.])
- use_reduce_exports=no
]
)
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
AX_CHECK_COMPILE_FLAG([-fvisibility=hidden],[RE_CXXFLAGS="-fvisibility=hidden"],
- [
- if test x$use_reduce_exports = xyes; then
- AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduced-exports.])
- fi
- AC_MSG_WARN([Cannot set default symbol visibility. Disabling reduced exports.])
- use_reduce_exports=no
- ])
+ [AC_MSG_ERROR([Cannot set default symbol visibility. Use --disable-reduce-exports.])])
fi
LEVELDB_CPPFLAGS=
@@ -533,7 +530,7 @@ AX_BOOST_THREAD
AX_BOOST_CHRONO
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
AC_MSG_CHECKING([for working boost reduced exports])
TEMP_CPPFLAGS="$CPPFLAGS"
CPPFLAGS="$BOOST_CPPFLAGS $CPPFLAGS"
@@ -547,25 +544,14 @@ if test x$use_reduce_exports != xno; then
#endif
]])],[
AC_MSG_RESULT(yes)
- ],[:
- if test x$use_reduce_exports = xauto; then
- use_reduce_exports=no
- else
- if test x$use_reduce_exports = xyes; then
- AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduced-exports.])
- fi
- fi
- AC_MSG_RESULT(no)
- AC_MSG_WARN([boost versions < 1.49 are known to have symbol visibility issues. Disabling reduced exports.])
+ ],[
+ AC_MSG_ERROR([boost versions < 1.49 are known to be broken with reduced exports. Use --disable-reduce-exports.])
])
CPPFLAGS="$TEMP_CPPFLAGS"
fi
-
-elif test x$use_reduce_exports = xauto; then
- use_reduce_exports=yes
fi
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
CXXFLAGS="$CXXFLAGS $RE_CXXFLAGS"
AX_CHECK_LINK_FLAG([[-Wl,--exclude-libs,ALL]], [RELDFLAGS="-Wl,--exclude-libs,ALL"])
fi
@@ -827,7 +813,7 @@ else
fi
AC_MSG_CHECKING([whether to reduce exports])
-if test x$use_reduce_exports != xno; then
+if test x$use_reduce_exports = xyes; then
AC_MSG_RESULT([yes])
else
AC_MSG_RESULT([no])
@@ -849,7 +835,6 @@ 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])
-AM_CONDITIONAL([USE_LIBSECP256K1],[test x$use_libsecp256k1 = xyes])
AC_DEFINE(CLIENT_VERSION_MAJOR, _CLIENT_VERSION_MAJOR, [Major version])
AC_DEFINE(CLIENT_VERSION_MINOR, _CLIENT_VERSION_MINOR, [Minor version])
diff --git a/contrib/debian/bitcoind.manpages b/contrib/debian/bitcoind.manpages
index 3e4ca63d4e..6d3e683855 100644
--- a/contrib/debian/bitcoind.manpages
+++ b/contrib/debian/bitcoind.manpages
@@ -1,2 +1,3 @@
debian/manpages/bitcoind.1
debian/manpages/bitcoin.conf.5
+debian/manpages/bitcoin-cli.1
diff --git a/contrib/debian/changelog b/contrib/debian/changelog
index fe910b65a5..7ce3babc1b 100644
--- a/contrib/debian/changelog
+++ b/contrib/debian/changelog
@@ -1,3 +1,15 @@
+bitcoin (0.10.0-precise1) precise; urgency=medium
+
+ * New upstream releases.
+
+ -- Matt Corallo (BlueMatt) <matt@mattcorallo.com> Wed, 18 Feb 2015 13:22:00 -1000
+
+bitcoin (0.9.4-precise1) precise; urgency=high
+
+ * New upstream releases.
+
+ -- Matt Corallo (laptop - only while traveling) <matt@mattcorallo.com> Mon, 12 Jan 2015 23:30:00 -1000
+
bitcoin (0.9.3-precise1) precise; urgency=medium
* New upstream releases.
diff --git a/contrib/debian/control b/contrib/debian/control
index a653260ad3..4392bb3385 100644
--- a/contrib/debian/control
+++ b/contrib/debian/control
@@ -12,7 +12,7 @@ Build-Depends: debhelper,
libdb4.8++-dev,
libssl-dev,
pkg-config,
- libminiupnpc8-dev,
+ libminiupnpc8-dev | libminiupnpc-dev (>> 1.6),
libboost-filesystem-dev (>> 1.35) | libboost-filesystem1.35-dev,
libboost-program-options-dev (>> 1.35) | libboost-program-options1.35-dev,
libboost-thread-dev (>> 1.35) | libboost-thread1.35-dev,
diff --git a/contrib/debian/manpages/bitcoin-cli.1 b/contrib/debian/manpages/bitcoin-cli.1
new file mode 100644
index 0000000000..f953ae9db7
--- /dev/null
+++ b/contrib/debian/manpages/bitcoin-cli.1
@@ -0,0 +1,48 @@
+.TH BITCOIN-CLI "1" "February 2015" "bitcoin-cli 0.10"
+.SH NAME
+bitcoin-cli \- a remote procedure call client for Bitcoin Core.
+.SH SYNOPSIS
+bitcoin-cli [options] <command> [params] \- Send command to Bitcoin Core.
+.TP
+bitcoin-cli [options] help \- Asks Bitcoin Core for a list of supported commands.
+.SH DESCRIPTION
+This manual page documents the bitcoin-cli program. bitcoin-cli is an RPC client used to send commands to Bitcoin Core.
+
+.SH OPTIONS
+.TP
+\fB\-?\fR
+Show the help message.
+.TP
+\fB\-conf=\fR<file>
+Specify configuration file (default: bitcoin.conf).
+.TP
+\fB\-datadir=\fR<dir>
+Specify data directory.
+.TP
+\fB\-testnet\fR
+Connect to a Bitcoin Core instance running in testnet mode.
+.TP
+\fB\-regtest\fR
+Connect to a Bitcoin Core instance running in regtest mode (see documentation for -regtest on bitcoind).
+.TP
+\fB\-rpcuser=\fR<user>
+Username for JSON\-RPC connections.
+.TP
+\fB\-rpcpassword=\fR<pw>
+Password for JSON\-RPC connections.
+.TP
+\fB\-rpcport=\fR<port>
+Listen for JSON\-RPC connections on <port> (default: 8332 or testnet: 18332).
+.TP
+\fB\-rpcconnect=\fR<ip>
+Send commands to node running on <ip> (default: 127.0.0.1).
+.TP
+\fB\-rpcssl\fR=\fI1\fR
+Use OpenSSL (https) for JSON\-RPC connections (see the Bitcoin Wiki for SSL setup instructions).
+
+.SH "SEE ALSO"
+\fBbitcoind\fP, \fBbitcoin.conf\fP
+.SH AUTHOR
+This manual page was written by Ciemon Dunville <ciemon@gmail.com>. Permission is granted to copy, distribute and/or modify this document under the terms of the MIT License.
+
+The complete text of the MIT License can be found on the web at \fIhttp://opensource.org/licenses/MIT\fP.
diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml
index 28bd9211ac..dde4af3491 100644
--- a/contrib/gitian-descriptors/gitian-linux.yml
+++ b/contrib/gitian-descriptors/gitian-linux.yml
@@ -15,6 +15,7 @@ packages:
- "faketime"
- "bsdmainutils"
- "binutils-gold"
+- "libstdc++6-4.6-pic"
reference_datetime: "2013-06-01 00:00:00"
remotes:
- "url": "https://github.com/bitcoin/bitcoin.git"
@@ -23,7 +24,7 @@ files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu"
- CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat"
+ CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat --enable-reduce-exports LDFLAGS=-static-libstdc++"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="date ar ranlib nm strip"
@@ -69,6 +70,14 @@ script: |
make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}"
done
+ # Ubuntu precise hack: Not an issue in later versions.
+ # Precise's libstdc++.a is non-pic. There's an optional libstdc++6-4.6-pic
+ # package which provides libstdc++_pic.a, but the linker can't find it.
+ # Symlink it to a path that will be included in our link-line so that the
+ # linker picks it up before the default libstdc++.a.
+ # This is only necessary for 64bit.
+ ln -s /usr/lib/gcc/x86_64-linux-gnu/4.6/libstdc++_pic.a ${BASEPREFIX}/x86_64-unknown-linux-gnu/lib/libstdc++.a
+
# Create the release tarball using (arbitrarily) the first host
./autogen.sh
./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'`
@@ -99,7 +108,7 @@ script: |
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
cd ../../
done
mkdir -p $OUTDIR/src
diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml
index 3ca42248d4..b401482c70 100644
--- a/contrib/gitian-descriptors/gitian-osx.yml
+++ b/contrib/gitian-descriptors/gitian-osx.yml
@@ -27,7 +27,7 @@ files:
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-apple-darwin11"
- CONFIGFLAGS="--enable-upnp-default GENISOIMAGE=$WRAP_DIR/genisoimage"
+ CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports GENISOIMAGE=$WRAP_DIR/genisoimage"
FAKETIME_HOST_PROGS=""
FAKETIME_PROGS="ar ranlib date dmg genisoimage"
@@ -126,7 +126,7 @@ script: |
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- find . | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
+ find ${DISTNAME} | sort | tar --no-recursion --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 -c -T - | gzip -9n > ${OUTDIR}/${DISTNAME}-${i}.tar.gz
cd ../../
done
mkdir -p $OUTDIR/src
diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml
index 4baa08c88d..2d72f7b6e5 100644
--- a/contrib/gitian-descriptors/gitian-win.yml
+++ b/contrib/gitian-descriptors/gitian-win.yml
@@ -26,7 +26,7 @@ files: []
script: |
WRAP_DIR=$HOME/wrapped
HOSTS="x86_64-w64-mingw32 i686-w64-mingw32"
- CONFIGFLAGS="--enable-upnp-default"
+ CONFIGFLAGS="--enable-upnp-default --enable-reduce-exports"
FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip"
FAKETIME_PROGS="date makensis zip"
@@ -106,7 +106,7 @@ script: |
find . -name "lib*.la" -delete
find . -name "lib*.a" -delete
rm -rf ${DISTNAME}/lib/pkgconfig
- find . -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
+ find ${DISTNAME} -type f | sort | zip -X@ ${OUTDIR}/${DISTNAME}-${i}.zip
cd ../..
done
mkdir -p $OUTDIR/src
diff --git a/contrib/gitian-downloader/fanquake-key.pgp b/contrib/gitian-downloader/fanquake-key.pgp
new file mode 100644
index 0000000000..9c03ff4522
--- /dev/null
+++ b/contrib/gitian-downloader/fanquake-key.pgp
@@ -0,0 +1,63 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG/MacGPG2 v2.0.26
+
+mQINBFFlV7oBEAC3dRAS7gSWQ1fV4JySD0HMBOtY+Y2oCX8vEuTI4atGcxbwXr4/
+OElRYhDK6Zirk8rMoKPxmr8OVek5LNnY3gcDffco6NXmZ+wTstQm6oqUxFfgzznG
+X/ExEVuCqiaPAwdWSKn9tC1GuOqRFcD+p2zmxw5mNH5XdsqaPSEGsKESY1IK+dMv
+K+YUrfrtexZyb66wCtupYziEeag6iEK/i2x2wewOji6IvtI+wB5FO+YMXw+LKucw
+PoHUOxjoz6YX3s04UxFaZo4R8x6J9XnJBSB2E5kfsSAzz3xR+zuapXY6H6mo/grq
+nr3c6ACcbAHnMWwQLYvWzde6iwswhyl0whebsajJH7Rd3G4c1U3L/oj4RwUFmZYU
+5Prs+Q5PepKAJfBeWCXZtUY2BNFCFj7b2H2NXYFR92Oc2GtoHAYACNeP070I9d3m
+IeuYhOrOckkunwaijUczq4rb3n3Vaq6YrdwZIzs8fALwc9Th98jj2dCUq0fljpSh
+UQFnPG83UsNkeWzUSgw+lBeEQqgOqUQQ293MbgRg0mJ8q677Iv+WaFqPKZzXxkwT
+QCCXhjcBmUKgXIHLFcbfmkR8pCcCToWXBD8CU441cBsootDD7SanPHbpcwZjt74x
+uLrVoCIyaju0T1jSrsPnm2A/8VkWLSCh1WRAlbjvMr7DwizGnRtzTiB6HQARAQAB
+tC9NaWNoYWVsIEZvcmQgKGJpdGNvaW4tb3RjKSA8ZmFucXVha2VAZ21haWwuY29t
+PokCNwQTAQoAIQUCUWVXugIbLwULCQgHAwUVCgkICwUWAgMBAAIeAQIXgAAKCRCU
+TTX5rD23agJgEAC0ouDjufjCMHL4DkaVkOnFbHzP+nR2Mq7pcjdiPNIt9tj8B6cI
+PRh/E+tt2iEJJ4lzlfj0uEqjqexmSBaMgY+pFb6ESg42EPQjRQ95oBoyZfp+uL/0
+KC3+Hh+EgmZGIFPZy2HneVfusiBUz2/YTOoqFkzmHalJe9Yvl2+dO0SUC7i6TUdJ
++ugSr/91hkjQC52LXgHzurH4zOz7ZjzRtZgUIG3oOx8mtEDf46eJ0IUsr+tWJqOp
+ce5xFh6nkKfS92B7YjGJ4YrkBHC7F9vmbrtIeuWiaxGzVqhHFmLvQe+4xyOpRgHM
+kcyD5uJNmSMO9gT3udut4hd0yUKg5rdqaUzqsvv19eNL/pZ7aBK2aDAK/yAi1T7X
+/nrhBJAU49zg1JRS6atRnhKSyd7wRSwVPJAXfVuelHsUgenSdLmSBxRha+9mL6Lb
+bLK/Dij/0r2fyhBJx4pV6V1n4BpHjv5ivkpgCvOupx8wx3PIxZq/rx+hK+ZBe2EQ
+7vq8rmLfBkSavHWyNxXEKWQed+mFS3d+Qsoy90bi7gQygIYNZOIBYwsy+qjCZ3om
+LwkzRjypH23ps7WmiaoenOaCjRYooNL4qtQwNVaDGYwvbMnXJ8Vb4/2j/Riz7+Ui
+BBVww+Wd72Fml/OFPDFep6HG/PuwFB9m5hmfSzrA01TIdjcWljtTDneufbkCDQRR
+ZVe6ARAAvi1IAxn9xKQCCqhsoKOiXNbpnmf6lYnoEwGtgI+0a0YQwtzm39P5T8P0
+esZ65/Re6jCCHLc23/urFPfW9VfrKPmNJncyzlx7OopJ7G1MWdRLEUzwqSaglC6x
+Zb4r1xR6eq2lBX6CAa5Q+AuAqkoGCEiYBpTyKij4sXE0c+Y9nIDIZhru7EnZvpL3
+SQvxzFryQLbWCGri0x9GKXZ2ZcDM7jRi/P+iX6yX6sVvOvyKz6NW2BI5OmpI1JbJ
+3fIXt/R6Wl2xpAFL/pxtYTYbfL6277HWtLDTqIkkRFKh64JdkH8n4G4m6VNUtGEu
+qP3SxtyShauxY44WzR0YX4rag6tU2Hks6h1JmyF8aQTBAkdP7UrQ0oxZ8f+iG9n6
+3GtTxgw2NyrqVMx3kBLm8DipyslbA2wCeZLrW6Co0j3pebJsDrMP/3zcmbJqRSLq
+qnkcxA4gn5j/N0oe8t26Y2WjovndhoR0QQxw8D/BKoMXbl0lvvRAtcnWtyG0COut
+AGB2PUbGdAX2Ky+uYKrG4uhu1edfV8JZVvB7NIQGzM2P8F9PrDRz7EtG6z7ky/pq
+HQwRbqwLWGs4QpQmHZchFmXH7pHmLC8i29W+xYhdeUstvx7oESbunICGrPjJOShJ
+G4191Zg0m/M6jeWV/v+piUXe3YVrgs42UWFusm5ZIduPUfgqUtkAEQEAAYkEPgQY
+AQoACQUCUWVXugIbLgIpCRCUTTX5rD23asFdIAQZAQoABgUCUWVXugAKCRAu659c
+wJUmwaduEACCiiRpBeKF5fSaM0cTb97hAHVQJL9Wk3xvA49YuROsSwtCzq9v+js5
+f/fE+QV/dIQUNwifEPQk8MqUVKpe1lIXwRp23GinzDAnOhfWnECqrMdR0dP99D49
+Zb7Dd4LDvP9c0mYtnX/78qQilxWmXhzDXcunnPsfCqsrduk9hMwkjmIrWFeSWSAg
+BEJDuZ4WLuqjni1udth0iZtZYrDaDgX/RWcTFW8QCc5hLsCRcInAxb75AWfWq6i/
+s3Ibg5tGm4+UfqGbFPuNyy6ow3ggqkovBp6ABMxe8dAYVXSmM2tKWZXBb3L6eho8
+QKKzyoezqpbQ2YUaYZ8XAdLuumXCtAHKP3/DI1JBefE0mxi1CXjdLK9sE5OO5KNt
+FXR8Dnot5C4BHrcaF6Iq2sqbhPxnhcDrEwv2mUgruD7n04LKIztAG0A35rcu6A2i
+IUq/PsXjS/5rX/p4CeYvnTTspXkhXgkvfhWz1cISXyfcNTWBKwOsLW4lY8bi05cv
+4Axl88tTg2dNYXIxSK7Jtu1YCEsZ8uaT3AAiTp1sKAOcRX8hIOTmPPxMxbIm8yg1
+jl71ovsV5rAyuVTUouFnljXyuLWXLotUOkmC6DjJUuRaxzt23/eByJ45x94T/A2U
+iT1oU+voigQGARrDkApXlgSI4oekg3Zgq57y6toV9F7o9A1PMtBq3AvDD/0as1K0
+wCRZIXinSwW2F6tFnVV+z+vvE0i54yHaskkuJYZRSQ/yJR1VgmW/BtAr7ooXF7l+
+9g7XOH7D8T28h+m4ABLN5ZDOxfTMZuV5Y4MnELh4dlBIfKGG2kjmW8+y/PUqMMGE
+BYRmGOD1qtWvFYoZ2ss5yrlvfenRRhQbIYSRz/YiT8OTogaNcYNpArUwT4z+05af
+kdxx0AaqauHqKRo/XTO5GIZQ6NbtPH6G++2Ie+oP8AyBWEpL3rvjZpzn7jxTBXMc
+MOMmhnb0Go4hD+BSphgDTZOgMLOLcorjb1Ct2VnajxPZD0aTB13SCgZjJhs9j3on
+EoI3gTHkRgiBjMBNtw7iaAumIRgrDwGzyuIL6bbyfDnbE02zxCqkYP6P0u48FGLs
+E4U60GrYSlFxa1MexF+HIPgqWsTOv4D2zXEJYvm1XEu1VOGQUkw7J5RFTDxHgkbh
+qvmkZ492iW2IC4L9hSdSqiZ5LhD2JwpgrMt8vrCzVitkjYQnXJ6WbWYfCybPsmLb
+mfQ03i9E+a50UC2SGDf8e3oxImAbbXLP/LyI7oczCxyb0EzcQlIIOtBgl3gI6KAh
+PTRQGeHCzIOSgUf7B0ihY7qiDeR1OshvTY0wdykdS0c+hzwuS5TZvfY4YM7Tssvt
+XwbdK0Zpx/oDtRHpuDMGKJBV2LWAZYkEbFsmtg==
+=3o2I
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/contrib/gitian-downloader/jonasschnelli-key.pgp b/contrib/gitian-downloader/jonasschnelli-key.pgp
new file mode 100644
index 0000000000..fe44c0fbd4
--- /dev/null
+++ b/contrib/gitian-downloader/jonasschnelli-key.pgp
Binary files differ
diff --git a/contrib/gitian-downloader/jonasschnelli.pgp b/contrib/gitian-downloader/jonasschnelli.pgp
deleted file mode 100644
index 96140fe171..0000000000
--- a/contrib/gitian-downloader/jonasschnelli.pgp
+++ /dev/null
Binary files differ
diff --git a/depends/Makefile b/depends/Makefile
index e2ef7ee49b..05ef33f2ee 100644
--- a/depends/Makefile
+++ b/depends/Makefile
@@ -6,7 +6,6 @@ SDK_PATH ?= $(BASEDIR)/SDKs
NO_QT ?=
NO_WALLET ?=
NO_UPNP ?=
-USE_LINUX_STATIC_QT5 ?=
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
BUILD = $(shell ./config.guess)
diff --git a/depends/README.usage b/depends/README.usage
index f5aa5314a1..24e1231d82 100644
--- a/depends/README.usage
+++ b/depends/README.usage
@@ -23,7 +23,6 @@ NO_QT: Don't download/build/cache qt and its dependencies
NO_WALLET: Don't download/build/cache libs needed to enable the wallet
NO_UPNP: Don't download/build/cache packages needed for enabling upnp
DEBUG: disable some optimizations and enable more runtime checking
-USE_LINUX_STATIC_QT5: Build a static qt5 rather than shared qt4. Linux only.
If some packages are not built, for example 'make NO_WALLET=1', the appropriate
options will be passed to bitcoin's configure. In this case, --disable-wallet.
diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk
index 08fd8a5247..03908aba59 100644
--- a/depends/packages/packages.mk
+++ b/depends/packages/packages.mk
@@ -4,15 +4,10 @@ native_packages := native_ccache native_comparisontool
qt_native_packages = native_protobuf
qt_packages = qrencode protobuf
-qt46_linux_packages = qt46 expat dbus libxcb xcb_proto libXau xproto freetype libX11 xextproto libXext xtrans libICE libSM
-qt5_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
-
+qt_linux_packages= qt expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans
qt_darwin_packages=qt
qt_mingw32_packages=qt
-qt_linux_$(USE_LINUX_STATIC_QT5):=$(qt5_linux_packages)
-qt_linux_:=$(qt46_linux_packages)
-qt_linux_packages:=$(qt_linux_$(USE_LINUX_STATIC_QT5))
wallet_packages=bdb
diff --git a/doc/REST-interface.md b/doc/REST-interface.md
index 0af650b4e8..23154ee903 100644
--- a/doc/REST-interface.md
+++ b/doc/REST-interface.md
@@ -10,6 +10,8 @@ Supported API
Given a transaction hash,
Returns a transaction, in binary, hex-encoded binary or JSON formats.
+For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
+
`GET /rest/block/BLOCK-HASH.{bin|hex|json}`
`GET /rest/block/notxdetails/BLOCK-HASH.{bin|hex|json}`
@@ -20,7 +22,17 @@ The HTTP request and response are both handled entirely in-memory, thus making m
With the /notxdetails/ option JSON response will only contain the transaction hash instead of the complete transaction details. The option only affects the JSON response.
-For full TX query capability, one must enable the transaction index via "txindex=1" command line / configuration option.
+`GET /rest/chaininfo.json`
+
+Returns various state info regarding block chain processing.
+Only supports JSON as output format.
+* chain : (string) current network name as defined in BIP70 (main, test, regtest)
+* blocks : (numeric) the current number of blocks processed in the server
+* headers : (numeric) the current number of headers we have validated
+* bestblockhash : (string) the hash of the currently best block
+* difficulty : (numeric) the current difficulty
+* verificationprogress : (numeric) estimate of verification progress [0..1]
+* chainwork : (string) total amount of work in active chain, in hexadecimal
Risks
-------------
diff --git a/doc/bips.md b/doc/bips.md
new file mode 100644
index 0000000000..579eadfff3
--- /dev/null
+++ b/doc/bips.md
@@ -0,0 +1,18 @@
+BIPs that are implemented by Bitcoin Core (up-to-date up to **v0.10.0**):
+
+* [`BIP 11`](https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki): Multisig outputs are standard since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 13`](https://github.com/bitcoin/bips/blob/master/bip-0013.mediawiki): The address format for P2SH addresses has been implemented since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 14`](https://github.com/bitcoin/bips/blob/master/bip-0014.mediawiki): The subversion string is being used as User Agent since **v0.6.0** ([PR #669](https://github.com/bitcoin/bitcoin/pull/669)).
+* [`BIP 16`](https://github.com/bitcoin/bips/blob/master/bip-0016.mediawiki): The pay-to-script-hash evaluation rules have been implemented since **v0.6.0**, and took effect on *April 1st 2012* ([PR #748](https://github.com/bitcoin/bitcoin/pull/748)).
+* [`BIP 21`](https://github.com/bitcoin/bips/blob/master/bip-0021.mediawiki): The URI format for Bitcoin payments has been implemented since **v0.6.0** ([PR #176](https://github.com/bitcoin/bitcoin/pull/176)).
+* [`BIP 22`](https://github.com/bitcoin/bips/blob/master/bip-0022.mediawiki): The 'getblocktemplate' (GBT) RPC protocol for mining has been implemented since **v0.7.0** ([PR #936](https://github.com/bitcoin/bitcoin/pull/936)).
+* [`BIP 23`](https://github.com/bitcoin/bips/blob/master/bip-0023.mediawiki): Some extensions to GBT have been implemented since **v0.10.0rc1**, including longpolling and block proposals ([PR #1816](https://github.com/bitcoin/bitcoin/pull/1816)).
+* [`BIP 30`](https://github.com/bitcoin/bips/blob/master/bip-0030.mediawiki): The evaluation rules to forbid creating new transactions with the same txid as previous not-fully-spent transactions were implemented since **v0.6.0**, and the rule took effect on *March 15th 2012* ([PR #915](https://github.com/bitcoin/bitcoin/pull/915)).
+* [`BIP 31`](https://github.com/bitcoin/bips/blob/master/bip-0031.mediawiki): The 'pong' protocol message (and the protocol version bump to 60001) has been implemented since **v0.6.1** ([PR #1081](https://github.com/bitcoin/bitcoin/pull/1081)).
+* [`BIP 34`](https://github.com/bitcoin/bips/blob/master/bip-0034.mediawiki): The rule that requires blocks to contain their height (number) in the coinbase input, and the introduction of version 2 blocks has been implemented since **v0.7.0**. The rule took effect for version 2 blocks as of *block 224413* (March 5th 2013), and version 1 blocks are no longer allowed since *block 227931* (March 25th 2013) ([PR #1526](https://github.com/bitcoin/bitcoin/pull/1526)).
+* [`BIP 35`](https://github.com/bitcoin/bips/blob/master/bip-0035.mediawiki): The 'mempool' protocol message (and the protocol version bump to 60002) has been implemented since **v0.7.0** ([PR #1641](https://github.com/bitcoin/bitcoin/pull/1641)).
+* [`BIP 37`](https://github.com/bitcoin/bips/blob/master/bip-0037.mediawiki): The bloom filtering for transaction relaying, partial merkle trees for blocks , and the protocol version bump to 70001 (enabling low-bandwidth SPV clients) has been implemented since **v0.8.0** ([PR #1795](https://github.com/bitcoin/bitcoin/pull/1795)).
+* [`BIP 42`](https://github.com/bitcoin/bips/blob/master/bip-0042.mediawiki): The bug that would have caused the subsidy schedule to resume after block 13440000 was fixed in **v0.9.2** ([PR #3842](https://github.com/bitcoin/bitcoin/pull/3842)).
+* [`BIP 61`](https://github.com/bitcoin/bips/blob/master/bip-0061.mediawiki): The 'reject' protocol message (and the protocol version bump to 70002) was added in **v0.9.0** ([PR #3185](https://github.com/bitcoin/bitcoin/pull/3185)).
+* [`BIP 66`](https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki): The strict DER rules and associated version 3 blocks have been implemented since **v0.10.0** ([PR #5713](https://github.com/bitcoin/bitcoin/pull/5713)).
+* [`BIP 70`](https://github.com/bitcoin/bips/blob/master/bip-0070.mediawiki) [`71`](https://github.com/bitcoin/bips/blob/master/bip-0071.mediawiki) [`72`](https://github.com/bitcoin/bips/blob/master/bip-0072.mediawiki): Payment Protocol support has been available in Bitcoin Core GUI since **v0.9.0** ([PR #5216](https://github.com/bitcoin/bitcoin/pull/5216)).
diff --git a/doc/release-process.md b/doc/release-process.md
index 363465d827..016090c594 100644
--- a/doc/release-process.md
+++ b/doc/release-process.md
@@ -130,6 +130,7 @@ gpg --digest-algo sha256 --clearsign SHA256SUMS # outputs SHA256SUMS.asc
rm SHA256SUMS
```
(the digest algorithm is forced to sha256 to avoid confusion of the `Hash:` header that GPG adds with the SHA256 used for the files)
+Note: check that SHA256SUMS itself doesn't end up in SHA256SUMS, which is a spurious/nonsensical entry.
- Upload zips and installers, as well as `SHA256SUMS.asc` from last step, to the bitcoin.org server
diff --git a/doc/unit-tests.md b/doc/unit-tests.md
index f1d3a8bc50..72613054b9 100644
--- a/doc/unit-tests.md
+++ b/doc/unit-tests.md
@@ -12,7 +12,7 @@ To add more bitcoind tests, add `BOOST_AUTO_TEST_CASE` functions to the existing
.cpp files in the test/ directory or add new .cpp files that
implement new BOOST_AUTO_TEST_SUITE sections.
-To run the bitcoin-qt tests manually, launch src/qt/test/bitcoin-qt_test
+To run the bitcoin-qt tests manually, launch src/qt/test/test_bitcoin-qt
To add more bitcoin-qt tests, add them to the `src/qt/test/` directory and
the `src/qt/test/test_main.cpp` file.
diff --git a/qa/rpc-tests/rest.py b/qa/rpc-tests/rest.py
index 704d889739..a9d41cf367 100755
--- a/qa/rpc-tests/rest.py
+++ b/qa/rpc-tests/rest.py
@@ -78,7 +78,7 @@ class RESTTest (BitcoinTestFramework):
# check hex format response
hex_string = http_get_call(url.hostname, url.port, '/rest/tx/'+tx_hash+self.FORMAT_SEPARATOR+"hex", True)
- assert_equal(response.status, 200)
+ assert_equal(hex_string.status, 200)
assert_greater_than(int(response.getheader('content-length')), 10)
# check block tx details
@@ -106,5 +106,12 @@ class RESTTest (BitcoinTestFramework):
for tx in txs:
assert_equal(tx in json_obj['tx'], True)
+ #test rest bestblock
+ bb_hash = self.nodes[0].getbestblockhash()
+
+ json_string = http_get_call(url.hostname, url.port, '/rest/chaininfo.json')
+ json_obj = json.loads(json_string)
+ assert_equal(json_obj['bestblockhash'], bb_hash)
+
if __name__ == '__main__':
RESTTest ().main ()
diff --git a/src/Makefile.am b/src/Makefile.am
index 009c3c5196..da65efa713 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -123,6 +123,7 @@ BITCOIN_CORE_H = \
script/standard.h \
serialize.h \
streams.h \
+ support/cleanse.h \
sync.h \
threadsafety.h \
timedata.h \
@@ -140,6 +141,8 @@ BITCOIN_CORE_H = \
walletdb.h \
wallet.h \
wallet_ismine.h \
+ compat/byteswap.h \
+ compat/endian.h \
compat/sanity.h
JSON_H = \
@@ -268,6 +271,7 @@ libbitcoin_util_a_SOURCES = \
compat/strnlen.cpp \
random.cpp \
rpcprotocol.cpp \
+ support/cleanse.cpp \
sync.cpp \
uint256.cpp \
util.cpp \
@@ -278,7 +282,6 @@ libbitcoin_util_a_SOURCES = \
if GLIBC_BACK_COMPAT
libbitcoin_util_a_SOURCES += compat/glibc_compat.cpp
-libbitcoin_util_a_SOURCES += compat/glibcxx_compat.cpp
endif
# cli: shared between bitcoin-cli and bitcoin-qt
@@ -370,16 +373,12 @@ libbitcoinconsensus_la_SOURCES = \
if GLIBC_BACK_COMPAT
libbitcoinconsensus_la_SOURCES += compat/glibc_compat.cpp
- libbitcoinconsensus_la_SOURCES += compat/glibcxx_compat.cpp
endif
libbitcoinconsensus_la_LDFLAGS = -no-undefined $(RELDFLAGS)
libbitcoinconsensus_la_LIBADD = $(CRYPTO_LIBS)
libbitcoinconsensus_la_CPPFLAGS = $(CRYPTO_CFLAGS) -I$(builddir)/obj -DBUILD_BITCOIN_INTERNAL
-if USE_LIBSECP256K1
-libbitcoinconsensus_la_LIBADD += secp256k1/libsecp256k1.la
-endif
endif
#
diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index 90494439fa..6774745de2 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -55,6 +55,7 @@ BITCOIN_TESTS =\
test/multisig_tests.cpp \
test/netbase_tests.cpp \
test/pmt_tests.cpp \
+ test/pow_tests.cpp \
test/rpc_tests.cpp \
test/sanity_tests.cpp \
test/script_P2SH_tests.cpp \
diff --git a/src/allocators.h b/src/allocators.h
index 6a131c3517..8ffe015b9e 100644
--- a/src/allocators.h
+++ b/src/allocators.h
@@ -6,6 +6,8 @@
#ifndef BITCOIN_ALLOCATORS_H
#define BITCOIN_ALLOCATORS_H
+#include "support/cleanse.h"
+
#include <map>
#include <string>
#include <string.h>
@@ -14,8 +16,6 @@
#include <boost/thread/mutex.hpp>
#include <boost/thread/once.hpp>
-#include <openssl/crypto.h> // for OPENSSL_cleanse()
-
/**
* Thread-safe class to keep track of locked (ie, non-swappable) memory pages.
*
@@ -174,7 +174,7 @@ void LockObject(const T& t)
template <typename T>
void UnlockObject(const T& t)
{
- OPENSSL_cleanse((void*)(&t), sizeof(T));
+ memory_cleanse((void*)(&t), sizeof(T));
LockedPageManager::Instance().UnlockRange((void*)(&t), sizeof(T));
}
@@ -217,7 +217,7 @@ struct secure_allocator : public std::allocator<T> {
void deallocate(T* p, std::size_t n)
{
if (p != NULL) {
- OPENSSL_cleanse(p, sizeof(T) * n);
+ memory_cleanse(p, sizeof(T) * n);
LockedPageManager::Instance().UnlockRange(p, sizeof(T) * n);
}
std::allocator<T>::deallocate(p, n);
@@ -254,7 +254,7 @@ struct zero_after_free_allocator : public std::allocator<T> {
void deallocate(T* p, std::size_t n)
{
if (p != NULL)
- OPENSSL_cleanse(p, sizeof(T) * n);
+ memory_cleanse(p, sizeof(T) * n);
std::allocator<T>::deallocate(p, n);
}
};
diff --git a/src/arith_uint256.cpp b/src/arith_uint256.cpp
index 1243823da5..2e61363576 100644
--- a/src/arith_uint256.cpp
+++ b/src/arith_uint256.cpp
@@ -7,6 +7,7 @@
#include "uint256.h"
#include "utilstrencodings.h"
+#include "crypto/common.h"
#include <stdio.h>
#include <string.h>
@@ -246,14 +247,14 @@ uint32_t arith_uint256::GetCompact(bool fNegative) const
uint256 ArithToUint256(const arith_uint256 &a)
{
uint256 b;
- // TODO: needs bswap32 on big-endian
- memcpy(b.begin(), a.pn, a.size());
+ for(int x=0; x<a.WIDTH; ++x)
+ WriteLE32(b.begin() + x*4, a.pn[x]);
return b;
}
arith_uint256 UintToArith256(const uint256 &a)
{
arith_uint256 b;
- // TODO: needs bswap32 on big-endian
- memcpy(b.pn, a.begin(), a.size());
+ for(int x=0; x<b.WIDTH; ++x)
+ b.pn[x] = ReadLE32(a.begin() + x*4);
return b;
}
diff --git a/src/base58.cpp b/src/base58.cpp
index 980d3cbf42..c809185056 100644
--- a/src/base58.cpp
+++ b/src/base58.cpp
@@ -172,7 +172,7 @@ bool CBase58Data::SetString(const char* psz, unsigned int nVersionBytes)
vchData.resize(vchTemp.size() - nVersionBytes);
if (!vchData.empty())
memcpy(&vchData[0], &vchTemp[nVersionBytes], vchData.size());
- OPENSSL_cleanse(&vchTemp[0], vchData.size());
+ memory_cleanse(&vchTemp[0], vchData.size());
return true;
}
diff --git a/src/bitcoind.cpp b/src/bitcoind.cpp
index 8a1745b50d..a0a96c2dfa 100644
--- a/src/bitcoind.cpp
+++ b/src/bitcoind.cpp
@@ -33,7 +33,7 @@
static bool fDaemon;
-void DetectShutdownThread(boost::thread_group* threadGroup)
+void WaitForShutdown(boost::thread_group* threadGroup)
{
bool fShutdown = ShutdownRequested();
// Tell the main threads to shutdown.
@@ -56,7 +56,6 @@ void DetectShutdownThread(boost::thread_group* threadGroup)
bool AppInit(int argc, char* argv[])
{
boost::thread_group threadGroup;
- boost::thread* detectShutdownThread = NULL;
bool fRet = false;
@@ -144,7 +143,6 @@ bool AppInit(int argc, char* argv[])
#endif
SoftSetBoolArg("-server", true);
- detectShutdownThread = new boost::thread(boost::bind(&DetectShutdownThread, &threadGroup));
fRet = AppInit2(threadGroup);
}
catch (const std::exception& e) {
@@ -155,20 +153,12 @@ bool AppInit(int argc, char* argv[])
if (!fRet)
{
- if (detectShutdownThread)
- detectShutdownThread->interrupt();
-
threadGroup.interrupt_all();
// threadGroup.join_all(); was left out intentionally here, because we didn't re-test all of
// the startup-failure cases to make sure they don't result in a hang due to some
// thread-blocking-waiting-for-another-thread-during-startup case
- }
-
- if (detectShutdownThread)
- {
- detectShutdownThread->join();
- delete detectShutdownThread;
- detectShutdownThread = NULL;
+ } else {
+ WaitForShutdown(&threadGroup);
}
Shutdown();
diff --git a/src/chain.h b/src/chain.h
index 004e87ab52..02f53cd2f2 100644
--- a/src/chain.h
+++ b/src/chain.h
@@ -48,6 +48,12 @@ struct CDiskBlockPos
void SetNull() { nFile = -1; nPos = 0; }
bool IsNull() const { return (nFile == -1); }
+
+ std::string ToString() const
+ {
+ return strprintf("CBlockDiskPos(nFile=%i, nPos=%i)", nFile, nPos);
+ }
+
};
enum BlockStatus {
diff --git a/src/chainparams.h b/src/chainparams.h
index f52bf4e55f..78b575d8f3 100644
--- a/src/chainparams.h
+++ b/src/chainparams.h
@@ -14,8 +14,6 @@
#include <vector>
-typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
-
struct CDNSSeedData {
std::string name, host;
CDNSSeedData(const std::string &strName, const std::string &strHost) : name(strName), host(strHost) {}
@@ -42,7 +40,7 @@ public:
};
const uint256& HashGenesisBlock() const { return hashGenesisBlock; }
- const MessageStartChars& MessageStart() const { return pchMessageStart; }
+ const CMessageHeader::MessageStartChars& MessageStart() const { return pchMessageStart; }
const std::vector<unsigned char>& AlertKey() const { return vAlertPubKey; }
int GetDefaultPort() const { return nDefaultPort; }
const arith_uint256& ProofOfWorkLimit() const { return bnProofOfWorkLimit; }
@@ -68,7 +66,7 @@ public:
bool RequireStandard() const { return fRequireStandard; }
int64_t TargetTimespan() const { return nTargetTimespan; }
int64_t TargetSpacing() const { return nTargetSpacing; }
- int64_t Interval() const { return nTargetTimespan / nTargetSpacing; }
+ int64_t DifficultyAdjustmentInterval() const { return nTargetTimespan / nTargetSpacing; }
/** Make miner stop after a block is found. In RPC, don't return until nGenProcLimit blocks are generated */
bool MineBlocksOnDemand() const { return fMineBlocksOnDemand; }
/** In the future use NetworkIDString() for RPC fields */
@@ -83,7 +81,7 @@ protected:
CChainParams() {}
uint256 hashGenesisBlock;
- MessageStartChars pchMessageStart;
+ CMessageHeader::MessageStartChars pchMessageStart;
//! Raw pub key bytes for the broadcast alert signing key.
std::vector<unsigned char> vAlertPubKey;
int nDefaultPort;
diff --git a/src/compat/byteswap.h b/src/compat/byteswap.h
new file mode 100644
index 0000000000..899220bdc5
--- /dev/null
+++ b/src/compat/byteswap.h
@@ -0,0 +1,47 @@
+// Copyright (c) 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 BITCOIN_COMPAT_BYTESWAP_H
+#define BITCOIN_COMPAT_BYTESWAP_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#if defined(HAVE_BYTESWAP_H)
+#include <byteswap.h>
+#endif
+
+#if HAVE_DECL_BSWAP_16 == 0
+inline uint16_t bswap_16(uint16_t x)
+{
+ return (x >> 8) | ((x & 0x00ff) << 8);
+}
+#endif // HAVE_DECL_BSWAP16
+
+#if HAVE_DECL_BSWAP_32 == 0
+inline uint32_t bswap_32(uint32_t x)
+{
+ return (((x & 0xff000000U) >> 24) | ((x & 0x00ff0000U) >> 8) |
+ ((x & 0x0000ff00U) << 8) | ((x & 0x000000ffU) << 24));
+}
+#endif // HAVE_DECL_BSWAP32
+
+#if HAVE_DECL_BSWAP_64 == 0
+inline uint64_t bswap_64(uint64_t x)
+{
+ return (((x & 0xff00000000000000ull) >> 56)
+ | ((x & 0x00ff000000000000ull) >> 40)
+ | ((x & 0x0000ff0000000000ull) >> 24)
+ | ((x & 0x000000ff00000000ull) >> 8)
+ | ((x & 0x00000000ff000000ull) << 8)
+ | ((x & 0x0000000000ff0000ull) << 24)
+ | ((x & 0x000000000000ff00ull) << 40)
+ | ((x & 0x00000000000000ffull) << 56));
+}
+#endif // HAVE_DECL_BSWAP64
+
+#endif // BITCOIN_COMPAT_BYTESWAP_H
diff --git a/src/compat/endian.h b/src/compat/endian.h
new file mode 100644
index 0000000000..4d041d6554
--- /dev/null
+++ b/src/compat/endian.h
@@ -0,0 +1,194 @@
+// Copyright (c) 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 BITCOIN_COMPAT_ENDIAN_H
+#define BITCOIN_COMPAT_ENDIAN_H
+
+#if defined(HAVE_CONFIG_H)
+#include "config/bitcoin-config.h"
+#endif
+
+#include <stdint.h>
+
+#include "compat/byteswap.h"
+
+#if defined(HAVE_ENDIAN_H)
+#include <endian.h>
+#endif
+
+#if defined(WORDS_BIGENDIAN)
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return big_endian_16bits;
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return bswap_16(little_endian_16bits);
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return big_endian_32bits;
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return bswap_32(little_endian_32bits);
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return big_endian_64bits;
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return bswap_64(little_endian_64bits);
+}
+#endif // HAVE_DECL_LE64TOH
+
+#else // WORDS_BIGENDIAN
+
+#if HAVE_DECL_HTOBE16 == 0
+inline uint16_t htobe16(uint16_t host_16bits)
+{
+ return bswap_16(host_16bits);
+}
+#endif // HAVE_DECL_HTOBE16
+
+#if HAVE_DECL_HTOLE16 == 0
+inline uint16_t htole16(uint16_t host_16bits)
+{
+ return host_16bits;
+}
+#endif // HAVE_DECL_HTOLE16
+
+#if HAVE_DECL_BE16TOH == 0
+inline uint16_t be16toh(uint16_t big_endian_16bits)
+{
+ return bswap_16(big_endian_16bits);
+}
+#endif // HAVE_DECL_BE16TOH
+
+#if HAVE_DECL_LE16TOH == 0
+inline uint16_t le16toh(uint16_t little_endian_16bits)
+{
+ return little_endian_16bits;
+}
+#endif // HAVE_DECL_LE16TOH
+
+#if HAVE_DECL_HTOBE32 == 0
+inline uint32_t htobe32(uint32_t host_32bits)
+{
+ return bswap_32(host_32bits);
+}
+#endif // HAVE_DECL_HTOBE32
+
+#if HAVE_DECL_HTOLE32 == 0
+inline uint32_t htole32(uint32_t host_32bits)
+{
+ return host_32bits;
+}
+#endif // HAVE_DECL_HTOLE32
+
+#if HAVE_DECL_BE32TOH == 0
+inline uint32_t be32toh(uint32_t big_endian_32bits)
+{
+ return bswap_32(big_endian_32bits);
+}
+#endif // HAVE_DECL_BE32TOH
+
+#if HAVE_DECL_LE32TOH == 0
+inline uint32_t le32toh(uint32_t little_endian_32bits)
+{
+ return little_endian_32bits;
+}
+#endif // HAVE_DECL_LE32TOH
+
+#if HAVE_DECL_HTOBE64 == 0
+inline uint64_t htobe64(uint64_t host_64bits)
+{
+ return bswap_64(host_64bits);
+}
+#endif // HAVE_DECL_HTOBE64
+
+#if HAVE_DECL_HTOLE64 == 0
+inline uint64_t htole64(uint64_t host_64bits)
+{
+ return host_64bits;
+}
+#endif // HAVE_DECL_HTOLE64
+
+#if HAVE_DECL_BE64TOH == 0
+inline uint64_t be64toh(uint64_t big_endian_64bits)
+{
+ return bswap_64(big_endian_64bits);
+}
+#endif // HAVE_DECL_BE64TOH
+
+#if HAVE_DECL_LE64TOH == 0
+inline uint64_t le64toh(uint64_t little_endian_64bits)
+{
+ return little_endian_64bits;
+}
+#endif // HAVE_DECL_LE64TOH
+
+#endif // WORDS_BIGENDIAN
+
+#endif // BITCOIN_COMPAT_ENDIAN_H
diff --git a/src/compat/glibcxx_compat.cpp b/src/compat/glibcxx_compat.cpp
deleted file mode 100644
index 4f2771e57a..0000000000
--- a/src/compat/glibcxx_compat.cpp
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright (c) 2009-2014 The Bitcoin Core developers
-// Distributed under the MIT software license, see the accompanying
-// file COPYING or http://www.opensource.org/licenses/mit-license.php.
-
-#include <cstddef>
-#include <istream>
-#include <stdexcept>
-#include <typeinfo>
-
-#ifndef _GLIBCXX_USE_NOEXCEPT
-#define _GLIBCXX_USE_NOEXCEPT throw()
-#endif
-
-namespace std
-{
-const char* bad_exception::what() const throw()
-{
- return "std::bad_exception";
-}
-
-const char* bad_cast::what() const throw()
-{
- return "std::bad_cast";
-}
-
-const char* bad_alloc::what() const throw()
-{
- return "std::bad_alloc";
-}
-
-namespace __detail
-{
-struct _List_node_base {
- void _M_hook(std::__detail::_List_node_base* const __position) throw() __attribute__((used))
- {
- _M_next = __position;
- _M_prev = __position->_M_prev;
- __position->_M_prev->_M_next = this;
- __position->_M_prev = this;
- }
-
- void _M_unhook() __attribute__((used))
- {
- _List_node_base* const __next_node = _M_next;
- _List_node_base* const __prev_node = _M_prev;
- __prev_node->_M_next = __next_node;
- __next_node->_M_prev = __prev_node;
- }
-
- _List_node_base* _M_next;
- _List_node_base* _M_prev;
-};
-} // namespace detail
-
-template ostream& ostream::_M_insert(bool);
-template ostream& ostream::_M_insert(long);
-template ostream& ostream::_M_insert(double);
-template ostream& ostream::_M_insert(unsigned long);
-template ostream& ostream::_M_insert(const void*);
-template ostream& __ostream_insert(ostream&, const char*, streamsize);
-template istream& istream::_M_extract(long&);
-template istream& istream::_M_extract(unsigned short&);
-
-out_of_range::~out_of_range() _GLIBCXX_USE_NOEXCEPT {}
-
-length_error::~length_error() _GLIBCXX_USE_NOEXCEPT {}
-
-// Used with permission.
-// See: https://github.com/madlib/madlib/commit/c3db418c0d34d6813608f2137fef1012ce03043d
-
-void ctype<char>::_M_widen_init() const
-{
- char __tmp[sizeof(_M_widen)];
- for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
- __tmp[__i] = __i;
- do_widen(__tmp, __tmp + sizeof(__tmp), _M_widen);
-
- _M_widen_ok = 1;
- // Set _M_widen_ok to 2 if memcpy can't be used.
- for (unsigned __i = 0; __i < sizeof(_M_widen); ++__i)
- if (__tmp[__i] != _M_widen[__i]) {
- _M_widen_ok = 2;
- break;
- }
-}
-
-void __throw_out_of_range_fmt(const char*, ...) __attribute__((__noreturn__));
-void __throw_out_of_range_fmt(const char* err, ...)
-{
- // Safe and over-simplified version. Ignore the format and print it as-is.
- __throw_out_of_range(err);
-}
-
-} // namespace std
diff --git a/src/crypter.cpp b/src/crypter.cpp
index 75d84dbf13..c7f7e21679 100644
--- a/src/crypter.cpp
+++ b/src/crypter.cpp
@@ -26,8 +26,8 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v
if (i != (int)WALLET_CRYPTO_KEY_SIZE)
{
- OPENSSL_cleanse(chKey, sizeof(chKey));
- OPENSSL_cleanse(chIV, sizeof(chIV));
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
return false;
}
diff --git a/src/crypter.h b/src/crypter.h
index cbaf1562f0..8a91498e2e 100644
--- a/src/crypter.h
+++ b/src/crypter.h
@@ -82,8 +82,8 @@ public:
void CleanKey()
{
- OPENSSL_cleanse(chKey, sizeof(chKey));
- OPENSSL_cleanse(chIV, sizeof(chIV));
+ memory_cleanse(chKey, sizeof(chKey));
+ memory_cleanse(chIV, sizeof(chIV));
fKeySet = false;
}
diff --git a/src/crypto/common.h b/src/crypto/common.h
index 8b04b1f728..580c72f5a6 100644
--- a/src/crypto/common.h
+++ b/src/crypto/common.h
@@ -11,110 +11,56 @@
#include <stdint.h>
-#if defined(HAVE_ENDIAN_H)
-#include <endian.h>
-#endif
+#include "compat/endian.h"
+
+uint16_t static inline ReadLE16(const unsigned char* ptr)
+{
+ return le16toh(*((uint16_t*)ptr));
+}
uint32_t static inline ReadLE32(const unsigned char* ptr)
{
-#if HAVE_DECL_LE32TOH == 1
return le32toh(*((uint32_t*)ptr));
-#elif !defined(WORDS_BIGENDIAN)
- return *((uint32_t*)ptr);
-#else
- return ((uint32_t)ptr[3] << 24 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[0]);
-#endif
}
uint64_t static inline ReadLE64(const unsigned char* ptr)
{
-#if HAVE_DECL_LE64TOH == 1
return le64toh(*((uint64_t*)ptr));
-#elif !defined(WORDS_BIGENDIAN)
- return *((uint64_t*)ptr);
-#else
- return ((uint64_t)ptr[7] << 56 | (uint64_t)ptr[6] << 48 | (uint64_t)ptr[5] << 40 | (uint64_t)ptr[4] << 32 |
- (uint64_t)ptr[3] << 24 | (uint64_t)ptr[2] << 16 | (uint64_t)ptr[1] << 8 | (uint64_t)ptr[0]);
-#endif
+}
+
+void static inline WriteLE16(unsigned char* ptr, uint16_t x)
+{
+ *((uint16_t*)ptr) = htole16(x);
}
void static inline WriteLE32(unsigned char* ptr, uint32_t x)
{
-#if HAVE_DECL_HTOLE32 == 1
*((uint32_t*)ptr) = htole32(x);
-#elif !defined(WORDS_BIGENDIAN)
- *((uint32_t*)ptr) = x;
-#else
- ptr[3] = x >> 24;
- ptr[2] = x >> 16;
- ptr[1] = x >> 8;
- ptr[0] = x;
-#endif
}
void static inline WriteLE64(unsigned char* ptr, uint64_t x)
{
-#if HAVE_DECL_HTOLE64 == 1
*((uint64_t*)ptr) = htole64(x);
-#elif !defined(WORDS_BIGENDIAN)
- *((uint64_t*)ptr) = x;
-#else
- ptr[7] = x >> 56;
- ptr[6] = x >> 48;
- ptr[5] = x >> 40;
- ptr[4] = x >> 32;
- ptr[3] = x >> 24;
- ptr[2] = x >> 16;
- ptr[1] = x >> 8;
- ptr[0] = x;
-#endif
}
uint32_t static inline ReadBE32(const unsigned char* ptr)
{
-#if HAVE_DECL_BE32TOH == 1
return be32toh(*((uint32_t*)ptr));
-#else
- return ((uint32_t)ptr[0] << 24 | (uint32_t)ptr[1] << 16 | (uint32_t)ptr[2] << 8 | (uint32_t)ptr[3]);
-#endif
}
uint64_t static inline ReadBE64(const unsigned char* ptr)
{
-#if HAVE_DECL_BE64TOH == 1
return be64toh(*((uint64_t*)ptr));
-#else
- return ((uint64_t)ptr[0] << 56 | (uint64_t)ptr[1] << 48 | (uint64_t)ptr[2] << 40 | (uint64_t)ptr[3] << 32 |
- (uint64_t)ptr[4] << 24 | (uint64_t)ptr[5] << 16 | (uint64_t)ptr[6] << 8 | (uint64_t)ptr[7]);
-#endif
}
void static inline WriteBE32(unsigned char* ptr, uint32_t x)
{
-#if HAVE_DECL_HTOBE32 == 1
*((uint32_t*)ptr) = htobe32(x);
-#else
- ptr[0] = x >> 24;
- ptr[1] = x >> 16;
- ptr[2] = x >> 8;
- ptr[3] = x;
-#endif
}
void static inline WriteBE64(unsigned char* ptr, uint64_t x)
{
-#if HAVE_DECL_HTOBE64 == 1
*((uint64_t*)ptr) = htobe64(x);
-#else
- ptr[0] = x >> 56;
- ptr[1] = x >> 48;
- ptr[2] = x >> 40;
- ptr[3] = x >> 32;
- ptr[4] = x >> 24;
- ptr[5] = x >> 16;
- ptr[6] = x >> 8;
- ptr[7] = x;
-#endif
}
#endif // BITCOIN_CRYPTO_COMMON_H
diff --git a/src/db.cpp b/src/db.cpp
index a7f885135b..3246e4b67a 100644
--- a/src/db.cpp
+++ b/src/db.cpp
@@ -21,8 +21,6 @@
#include <boost/thread.hpp>
#include <boost/version.hpp>
-#include <openssl/rand.h>
-
using namespace std;
diff --git a/src/hash.cpp b/src/hash.cpp
index a7eb5a2a0b..20d5d21777 100644
--- a/src/hash.cpp
+++ b/src/hash.cpp
@@ -3,8 +3,10 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "hash.h"
+#include "crypto/common.h"
#include "crypto/hmac_sha512.h"
+
inline uint32_t ROTL32(uint32_t x, int8_t r)
{
return (x << r) | (x >> (32 - r));
@@ -23,10 +25,10 @@ unsigned int MurmurHash3(unsigned int nHashSeed, const std::vector<unsigned char
//----------
// body
- const uint32_t* blocks = (const uint32_t*)(&vDataToHash[0] + nblocks * 4);
+ const uint8_t* blocks = &vDataToHash[0] + nblocks * 4;
for (int i = -nblocks; i; i++) {
- uint32_t k1 = blocks[i];
+ uint32_t k1 = ReadLE32(blocks + i*4);
k1 *= c1;
k1 = ROTL32(k1, 15);
diff --git a/src/key.cpp b/src/key.cpp
index d8319db1a3..64c9bc7119 100644
--- a/src/key.cpp
+++ b/src/key.cpp
@@ -208,11 +208,9 @@ void CExtKey::Decode(const unsigned char code[74]) {
}
bool ECC_InitSanityCheck() {
-#if !defined(USE_SECP256K1)
if (!CECKey::SanityCheck()) {
return false;
}
-#endif
CKey key;
key.MakeNewKey(true);
CPubKey pubkey = key.GetPubKey();
diff --git a/src/main.cpp b/src/main.cpp
index a30084a75b..a2043dd9cb 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -1199,19 +1199,19 @@ bool ReadBlockFromDisk(CBlock& block, const CDiskBlockPos& pos)
// Open history file to read
CAutoFile filein(OpenBlockFile(pos, true), SER_DISK, CLIENT_VERSION);
if (filein.IsNull())
- return error("ReadBlockFromDisk: OpenBlockFile failed");
+ return error("ReadBlockFromDisk: OpenBlockFile failed for %s", pos.ToString());
// Read block
try {
filein >> block;
}
catch (const std::exception& e) {
- return error("%s: Deserialize or I/O error - %s", __func__, e.what());
+ return error("%s: Deserialize or I/O error - %s at %s", __func__, e.what(), pos.ToString());
}
// Check the header
if (!CheckProofOfWork(block.GetHash(), block.nBits))
- return error("ReadBlockFromDisk: Errors in block header");
+ return error("ReadBlockFromDisk: Errors in block header at %s", pos.ToString());
return true;
}
@@ -1221,7 +1221,8 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex)
if (!ReadBlockFromDisk(block, pindex->GetBlockPos()))
return false;
if (block.GetHash() != pindex->GetBlockHash())
- return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index");
+ return error("ReadBlockFromDisk(CBlock&, CBlockIndex*): GetHash() doesn't match index for %s at %s",
+ pindex->ToString(), pindex->GetBlockPos().ToString());
return true;
}
@@ -1588,6 +1589,39 @@ bool UndoReadFromDisk(CBlockUndo& blockundo, const CDiskBlockPos& pos, const uin
} // anon namespace
+/**
+ * Apply the undo operation of a CTxInUndo to the given chain state.
+ * @param undo The undo object.
+ * @param view The coins view to which to apply the changes.
+ * @param out The out point that corresponds to the tx input.
+ * @return True on success.
+ */
+static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, const COutPoint& out)
+{
+ bool fClean = true;
+
+ CCoinsModifier coins = view.ModifyCoins(out.hash);
+ if (undo.nHeight != 0) {
+ // undo data contains height: this is the last output of the prevout tx being spent
+ if (!coins->IsPruned())
+ fClean = fClean && error("%s: undo data overwriting existing transaction", __func__);
+ coins->Clear();
+ coins->fCoinBase = undo.fCoinBase;
+ coins->nHeight = undo.nHeight;
+ coins->nVersion = undo.nVersion;
+ } else {
+ if (coins->IsPruned())
+ fClean = fClean && error("%s: undo data adding output to missing transaction", __func__);
+ }
+ if (coins->IsAvailable(out.n))
+ fClean = fClean && error("%s: undo data overwriting existing output", __func__);
+ if (coins->vout.size() < out.n+1)
+ coins->vout.resize(out.n+1);
+ coins->vout[out.n] = undo.txout;
+
+ return fClean;
+}
+
bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool* pfClean)
{
assert(pindex->GetBlockHash() == view.GetBestBlock());
@@ -1613,11 +1647,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
uint256 hash = tx.GetHash();
// Check that all outputs are available and match the outputs in the block itself
- // exactly. Note that transactions with only provably unspendable outputs won't
- // have outputs available even in the block itself, so we handle that case
- // specially with outsEmpty.
+ // exactly.
{
- CCoins outsEmpty;
CCoinsModifier outs = view.ModifyCoins(hash);
outs->ClearUnspendable();
@@ -1642,24 +1673,8 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
for (unsigned int j = tx.vin.size(); j-- > 0;) {
const COutPoint &out = tx.vin[j].prevout;
const CTxInUndo &undo = txundo.vprevout[j];
- CCoinsModifier coins = view.ModifyCoins(out.hash);
- if (undo.nHeight != 0) {
- // undo data contains height: this is the last output of the prevout tx being spent
- if (!coins->IsPruned())
- fClean = fClean && error("DisconnectBlock(): undo data overwriting existing transaction");
- coins->Clear();
- coins->fCoinBase = undo.fCoinBase;
- coins->nHeight = undo.nHeight;
- coins->nVersion = undo.nVersion;
- } else {
- if (coins->IsPruned())
- fClean = fClean && error("DisconnectBlock(): undo data adding output to missing transaction");
- }
- if (coins->IsAvailable(out.n))
- fClean = fClean && error("DisconnectBlock(): undo data overwriting existing output");
- if (coins->vout.size() < out.n+1)
- coins->vout.resize(out.n+1);
- coins->vout[out.n] = undo.txout;
+ if (!ApplyTxInUndo(undo, view, out))
+ fClean = false;
}
}
}
@@ -1670,9 +1685,9 @@ bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex
if (pfClean) {
*pfClean = fClean;
return true;
- } else {
- return fClean;
}
+
+ return fClean;
}
void static FlushBlockFile(bool fFinalize = false)
@@ -3340,19 +3355,17 @@ void static ProcessGetData(CNode* pfrom)
BlockMap::iterator mi = mapBlockIndex.find(inv.hash);
if (mi != mapBlockIndex.end())
{
- // If the requested block is at a height below our last
- // checkpoint, only serve it if it's in the checkpointed chain
- int nHeight = mi->second->nHeight;
- CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint();
- if (pcheckpoint && nHeight < pcheckpoint->nHeight) {
- if (!chainActive.Contains(mi->second))
- {
- LogPrintf("ProcessGetData(): ignoring request for old block that isn't in the main chain\n");
- } else {
- send = true;
- }
- } else {
+ if (chainActive.Contains(mi->second)) {
send = true;
+ } else {
+ // To prevent fingerprinting attacks, only send blocks outside of the active
+ // chain if they are valid, and no more than a month older than the best header
+ // chain we know about.
+ send = mi->second->IsValid(BLOCK_VALID_SCRIPTS) && (pindexBestHeader != NULL) &&
+ (mi->second->GetBlockTime() > pindexBestHeader->GetBlockTime() - 30 * 24 * 60 * 60);
+ if (!send) {
+ LogPrintf("ProcessGetData(): ignoring request from peer=%i for old block that isn't in the main chain\n", pfrom->GetId());
+ }
}
}
if (send)
@@ -3450,7 +3463,7 @@ void static ProcessGetData(CNode* pfrom)
bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv, int64_t nTimeReceived)
{
RandAddSeedPerfmon();
- LogPrint("net", "received: %s (%u bytes) peer=%d\n", strCommand, vRecv.size(), pfrom->id);
+ LogPrint("net", "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->id);
if (mapArgs.count("-dropmessagestest") && GetRand(atoi(mapArgs["-dropmessagestest"])) == 0)
{
LogPrintf("dropmessagestest DROPPING RECV MESSAGE\n");
@@ -4290,16 +4303,16 @@ bool ProcessMessages(CNode* pfrom)
// Scan for message start
if (memcmp(msg.hdr.pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0) {
- LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", msg.hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: INVALID MESSAGESTART %s peer=%d\n", SanitizeString(msg.hdr.GetCommand()), pfrom->id);
fOk = false;
break;
}
// Read header
CMessageHeader& hdr = msg.hdr;
- if (!hdr.IsValid())
+ if (!hdr.IsValid(Params().MessageStart()))
{
- LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", hdr.GetCommand(), pfrom->id);
+ LogPrintf("PROCESSMESSAGE: ERRORS IN HEADER %s peer=%d\n", SanitizeString(hdr.GetCommand()), pfrom->id);
continue;
}
string strCommand = hdr.GetCommand();
@@ -4310,12 +4323,11 @@ bool ProcessMessages(CNode* pfrom)
// Checksum
CDataStream& vRecv = msg.vRecv;
uint256 hash = Hash(vRecv.begin(), vRecv.begin() + nMessageSize);
- unsigned int nChecksum = 0;
- memcpy(&nChecksum, &hash, sizeof(nChecksum));
+ unsigned int nChecksum = ReadLE32((unsigned char*)&hash);
if (nChecksum != hdr.nChecksum)
{
LogPrintf("ProcessMessages(%s, %u bytes): CHECKSUM ERROR nChecksum=%08x hdr.nChecksum=%08x\n",
- strCommand, nMessageSize, nChecksum, hdr.nChecksum);
+ SanitizeString(strCommand), nMessageSize, nChecksum, hdr.nChecksum);
continue;
}
@@ -4332,12 +4344,12 @@ bool ProcessMessages(CNode* pfrom)
if (strstr(e.what(), "end of data"))
{
// Allow exceptions from under-length message on vRecv
- LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught, normally caused by a message being shorter than its stated length\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else if (strstr(e.what(), "size too large"))
{
// Allow exceptions from over-long size
- LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", strCommand, nMessageSize, e.what());
+ LogPrintf("ProcessMessages(%s, %u bytes): Exception '%s' caught\n", SanitizeString(strCommand), nMessageSize, e.what());
}
else
{
@@ -4354,7 +4366,7 @@ bool ProcessMessages(CNode* pfrom)
}
if (!fRet)
- LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", strCommand, nMessageSize, pfrom->id);
+ LogPrintf("ProcessMessage(%s, %u bytes) FAILED peer=%d\n", SanitizeString(strCommand), nMessageSize, pfrom->id);
break;
}
diff --git a/src/net.cpp b/src/net.cpp
index e4ab9d706d..0723ee218a 100644
--- a/src/net.cpp
+++ b/src/net.cpp
@@ -14,6 +14,7 @@
#include "clientversion.h"
#include "primitives/transaction.h"
#include "ui_interface.h"
+#include "crypto/common.h"
#ifdef WIN32
#include <string.h>
@@ -509,7 +510,7 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
// get current incomplete message, or create a new one
if (vRecvMsg.empty() ||
vRecvMsg.back().complete())
- vRecvMsg.push_back(CNetMessage(SER_NETWORK, nRecvVersion));
+ vRecvMsg.push_back(CNetMessage(Params().MessageStart(), SER_NETWORK, nRecvVersion));
CNetMessage& msg = vRecvMsg.back();
@@ -523,6 +524,11 @@ bool CNode::ReceiveMsgBytes(const char *pch, unsigned int nBytes)
if (handled < 0)
return false;
+ if (msg.in_data && msg.hdr.nMessageSize > MAX_PROTOCOL_MESSAGE_LENGTH) {
+ LogPrint("net", "Oversized message from peer=%i, disconnecting", GetId());
+ return false;
+ }
+
pch += handled;
nBytes -= handled;
@@ -1970,8 +1976,8 @@ void CNode::BeginMessage(const char* pszCommand) EXCLUSIVE_LOCK_FUNCTION(cs_vSen
{
ENTER_CRITICAL_SECTION(cs_vSend);
assert(ssSend.size() == 0);
- ssSend << CMessageHeader(pszCommand, 0);
- LogPrint("net", "sending: %s ", pszCommand);
+ ssSend << CMessageHeader(Params().MessageStart(), pszCommand, 0);
+ LogPrint("net", "sending: %s ", SanitizeString(pszCommand));
}
void CNode::AbortMessage() UNLOCK_FUNCTION(cs_vSend)
@@ -2002,7 +2008,7 @@ void CNode::EndMessage() UNLOCK_FUNCTION(cs_vSend)
// Set the size
unsigned int nSize = ssSend.size() - CMessageHeader::HEADER_SIZE;
- memcpy((char*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], &nSize, sizeof(nSize));
+ WriteLE32((uint8_t*)&ssSend[CMessageHeader::MESSAGE_SIZE_OFFSET], nSize);
// Set the checksum
uint256 hash = Hash(ssSend.begin() + CMessageHeader::HEADER_SIZE, ssSend.end());
diff --git a/src/net.h b/src/net.h
index b78665b5c6..7dd02b84ef 100644
--- a/src/net.h
+++ b/src/net.h
@@ -46,6 +46,8 @@ static const int TIMEOUT_INTERVAL = 20 * 60;
static const unsigned int MAX_INV_SZ = 50000;
/** The maximum number of new addresses to accumulate before announcing. */
static const unsigned int MAX_ADDR_TO_SEND = 1000;
+/** Maximum length of incoming protocol messages (no message over 2 MiB is currently acceptable). */
+static const unsigned int MAX_PROTOCOL_MESSAGE_LENGTH = 2 * 1024 * 1024;
/** -listen default */
static const bool DEFAULT_LISTEN = true;
/** -upnp default */
@@ -183,7 +185,7 @@ public:
int64_t nTime; // time (in microseconds) of message receipt.
- CNetMessage(int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), vRecv(nTypeIn, nVersionIn) {
+ CNetMessage(const CMessageHeader::MessageStartChars& pchMessageStartIn, int nTypeIn, int nVersionIn) : hdrbuf(nTypeIn, nVersionIn), hdr(pchMessageStartIn), vRecv(nTypeIn, nVersionIn) {
hdrbuf.resize(24);
in_data = false;
nHdrPos = 0;
@@ -570,9 +572,6 @@ public:
}
}
- bool IsSubscribed(unsigned int nChannel);
- void Subscribe(unsigned int nChannel, unsigned int nHops=0);
- void CancelSubscribe(unsigned int nChannel);
void CloseSocketDisconnect();
// Denial-of-service detection/prevention
diff --git a/src/netbase.h b/src/netbase.h
index 5bf13a673f..b42c2dffa4 100644
--- a/src/netbase.h
+++ b/src/netbase.h
@@ -162,7 +162,7 @@ class CService : public CNetAddr
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(FLATDATA(ip));
unsigned short portN = htons(port);
- READWRITE(portN);
+ READWRITE(FLATDATA(portN));
if (ser_action.ForRead())
port = ntohs(portN);
}
diff --git a/src/pow.cpp b/src/pow.cpp
index e49f0d104c..b75b293c90 100644
--- a/src/pow.cpp
+++ b/src/pow.cpp
@@ -20,8 +20,8 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
if (pindexLast == NULL)
return nProofOfWorkLimit;
- // Only change once per interval
- if ((pindexLast->nHeight+1) % Params().Interval() != 0)
+ // Only change once per difficulty adjustment interval
+ if ((pindexLast->nHeight+1) % Params().DifficultyAdjustmentInterval() != 0)
{
if (Params().AllowMinDifficultyBlocks())
{
@@ -34,7 +34,7 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
{
// Return the last non-special-min-difficulty-rules-block
const CBlockIndex* pindex = pindexLast;
- while (pindex->pprev && pindex->nHeight % Params().Interval() != 0 && pindex->nBits == nProofOfWorkLimit)
+ while (pindex->pprev && pindex->nHeight % Params().DifficultyAdjustmentInterval() != 0 && pindex->nBits == nProofOfWorkLimit)
pindex = pindex->pprev;
return pindex->nBits;
}
@@ -44,12 +44,17 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead
// Go back by what we want to be 14 days worth of blocks
const CBlockIndex* pindexFirst = pindexLast;
- for (int i = 0; pindexFirst && i < Params().Interval()-1; i++)
+ for (int i = 0; pindexFirst && i < Params().DifficultyAdjustmentInterval()-1; i++)
pindexFirst = pindexFirst->pprev;
assert(pindexFirst);
+ return CalculateNextWorkRequired(pindexLast, pindexFirst->GetBlockTime());
+}
+
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime)
+{
// Limit adjustment step
- int64_t nActualTimespan = pindexLast->GetBlockTime() - pindexFirst->GetBlockTime();
+ int64_t nActualTimespan = pindexLast->GetBlockTime() - nFirstBlockTime;
LogPrintf(" nActualTimespan = %d before bounds\n", nActualTimespan);
if (nActualTimespan < Params().TargetTimespan()/4)
nActualTimespan = Params().TargetTimespan()/4;
diff --git a/src/pow.h b/src/pow.h
index 3337a30a5e..a5fbba6236 100644
--- a/src/pow.h
+++ b/src/pow.h
@@ -14,6 +14,7 @@ class uint256;
class arith_uint256;
unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHeader *pblock);
+unsigned int CalculateNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime);
/** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */
bool CheckProofOfWork(uint256 hash, unsigned int nBits);
diff --git a/src/primitives/block.cpp b/src/primitives/block.cpp
index 3b4a360395..5b9c13d870 100644
--- a/src/primitives/block.cpp
+++ b/src/primitives/block.cpp
@@ -8,10 +8,11 @@
#include "hash.h"
#include "tinyformat.h"
#include "utilstrencodings.h"
+#include "crypto/common.h"
uint256 CBlockHeader::GetHash() const
{
- return Hash(BEGIN(nVersion), END(nNonce));
+ return SerializeHash(*this);
}
uint256 CBlock::BuildMerkleTree(bool* fMutated) const
diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h
index 1b5a47e0da..0ba9affeda 100644
--- a/src/primitives/transaction.h
+++ b/src/primitives/transaction.h
@@ -25,7 +25,8 @@ public:
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
- READWRITE(FLATDATA(*this));
+ READWRITE(hash);
+ READWRITE(n);
}
void SetNull() { hash.SetNull(); n = (uint32_t) -1; }
diff --git a/src/protocol.cpp b/src/protocol.cpp
index 74ac706d60..568580a595 100644
--- a/src/protocol.cpp
+++ b/src/protocol.cpp
@@ -5,7 +5,6 @@
#include "protocol.h"
-#include "chainparams.h"
#include "util.h"
#include "utilstrencodings.h"
@@ -21,17 +20,17 @@ static const char* ppszTypeName[] =
"filtered block"
};
-CMessageHeader::CMessageHeader()
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn)
{
- memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
nMessageSize = -1;
nChecksum = 0;
}
-CMessageHeader::CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn)
+CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn)
{
- memcpy(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE);
+ memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE);
memset(pchCommand, 0, sizeof(pchCommand));
strncpy(pchCommand, pszCommand, COMMAND_SIZE);
nMessageSize = nMessageSizeIn;
@@ -43,10 +42,10 @@ std::string CMessageHeader::GetCommand() const
return std::string(pchCommand, pchCommand + strnlen(pchCommand, COMMAND_SIZE));
}
-bool CMessageHeader::IsValid() const
+bool CMessageHeader::IsValid(const MessageStartChars& pchMessageStartIn) const
{
// Check start string
- if (memcmp(pchMessageStart, Params().MessageStart(), MESSAGE_START_SIZE) != 0)
+ if (memcmp(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE) != 0)
return false;
// Check the command string for errors
diff --git a/src/protocol.h b/src/protocol.h
index f8394ce52f..e838c0d363 100644
--- a/src/protocol.h
+++ b/src/protocol.h
@@ -29,11 +29,13 @@
class CMessageHeader
{
public:
- CMessageHeader();
- CMessageHeader(const char* pszCommand, unsigned int nMessageSizeIn);
+ typedef unsigned char MessageStartChars[MESSAGE_START_SIZE];
+
+ CMessageHeader(const MessageStartChars& pchMessageStartIn);
+ CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn);
std::string GetCommand() const;
- bool IsValid() const;
+ bool IsValid(const MessageStartChars& messageStart) const;
ADD_SERIALIZE_METHODS;
diff --git a/src/pubkey.cpp b/src/pubkey.cpp
index 3ae67ca5fe..a4c046bff5 100644
--- a/src/pubkey.cpp
+++ b/src/pubkey.cpp
@@ -6,25 +6,16 @@
#include "eccryptoverify.h"
-#ifdef USE_SECP256K1
-#include <secp256k1.h>
-#else
#include "ecwrapper.h"
-#endif
bool CPubKey::Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig) const {
if (!IsValid())
return false;
-#ifdef USE_SECP256K1
- if (secp256k1_ecdsa_verify((const unsigned char*)&hash, &vchSig[0], vchSig.size(), begin(), size()) != 1)
- return false;
-#else
CECKey key;
if (!key.SetPubKey(begin(), size()))
return false;
if (!key.Verify(hash, vchSig))
return false;
-#endif
return true;
}
@@ -33,52 +24,33 @@ bool CPubKey::RecoverCompact(const uint256 &hash, const std::vector<unsigned cha
return false;
int recid = (vchSig[0] - 27) & 3;
bool fComp = ((vchSig[0] - 27) & 4) != 0;
-#ifdef USE_SECP256K1
- int pubkeylen = 65;
- if (!secp256k1_ecdsa_recover_compact((const unsigned char*)&hash, &vchSig[1], (unsigned char*)begin(), &pubkeylen, fComp, recid))
- return false;
- assert((int)size() == pubkeylen);
-#else
CECKey key;
if (!key.Recover(hash, &vchSig[1], recid))
return false;
std::vector<unsigned char> pubkey;
key.GetPubKey(pubkey, fComp);
Set(pubkey.begin(), pubkey.end());
-#endif
return true;
}
bool CPubKey::IsFullyValid() const {
if (!IsValid())
return false;
-#ifdef USE_SECP256K1
- if (!secp256k1_ecdsa_pubkey_verify(begin(), size()))
- return false;
-#else
CECKey key;
if (!key.SetPubKey(begin(), size()))
return false;
-#endif
return true;
}
bool CPubKey::Decompress() {
if (!IsValid())
return false;
-#ifdef USE_SECP256K1
- int clen = size();
- int ret = secp256k1_ecdsa_pubkey_decompress((unsigned char*)begin(), &clen);
- assert(ret);
- assert(clen == (int)size());
-#else
CECKey key;
if (!key.SetPubKey(begin(), size()))
return false;
std::vector<unsigned char> pubkey;
key.GetPubKey(pubkey, false);
Set(pubkey.begin(), pubkey.end());
-#endif
return true;
}
@@ -89,17 +61,12 @@ bool CPubKey::Derive(CPubKey& pubkeyChild, unsigned char ccChild[32], unsigned i
unsigned char out[64];
BIP32Hash(cc, nChild, *begin(), begin()+1, out);
memcpy(ccChild, out+32, 32);
-#ifdef USE_SECP256K1
- pubkeyChild = *this;
- bool ret = secp256k1_ecdsa_pubkey_tweak_add((unsigned char*)pubkeyChild.begin(), pubkeyChild.size(), out);
-#else
CECKey key;
bool ret = key.SetPubKey(begin(), size());
ret &= key.TweakPublic(out);
std::vector<unsigned char> pubkey;
key.GetPubKey(pubkey, true);
pubkeyChild.Set(pubkey.begin(), pubkey.end());
-#endif
return ret;
}
diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp
index 09f784387e..1ec968ff2b 100644
--- a/src/qt/bitcoingui.cpp
+++ b/src/qt/bitcoingui.cpp
@@ -151,7 +151,7 @@ BitcoinGUI::BitcoinGUI(const NetworkStyle *networkStyle, QWidget *parent) :
// Create actions for the toolbar, menu bar and tray/dock icon
// Needs walletFrame to be initialized
- createActions(networkStyle);
+ createActions();
// Create application menu bar
createMenuBar();
@@ -243,7 +243,7 @@ BitcoinGUI::~BitcoinGUI()
delete rpcConsole;
}
-void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
+void BitcoinGUI::createActions()
{
QActionGroup *tabGroup = new QActionGroup(this);
@@ -340,6 +340,7 @@ void BitcoinGUI::createActions(const NetworkStyle *networkStyle)
openAction->setStatusTip(tr("Open a bitcoin: URI or payment request"));
showHelpMessageAction = new QAction(TextColorIcon(":/icons/info"), tr("&Command-line options"), this);
+ showHelpMessageAction->setMenuRole(QAction::NoRole);
showHelpMessageAction->setStatusTip(tr("Show the Bitcoin Core help message to get a list with possible Bitcoin command-line options"));
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
@@ -435,8 +436,8 @@ void BitcoinGUI::setClientModel(ClientModel *clientModel)
setNumConnections(clientModel->getNumConnections());
connect(clientModel, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(clientModel->getNumBlocks());
- connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+ setNumBlocks(clientModel->getNumBlocks(), clientModel->getLastBlockDate());
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
// Receive and report messages from client model
connect(clientModel, SIGNAL(message(QString,QString,unsigned int)), this, SLOT(message(QString,QString,unsigned int)));
@@ -652,7 +653,7 @@ void BitcoinGUI::setNumConnections(int count)
labelConnectionsIcon->setToolTip(tr("%n active connection(s) to Bitcoin network", "", count));
}
-void BitcoinGUI::setNumBlocks(int count)
+void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate)
{
if(!clientModel)
return;
@@ -680,9 +681,8 @@ void BitcoinGUI::setNumBlocks(int count)
QString tooltip;
- QDateTime lastBlockDate = clientModel->getLastBlockDate();
QDateTime currentDate = QDateTime::currentDateTime();
- int secs = lastBlockDate.secsTo(currentDate);
+ qint64 secs = blockDate.secsTo(currentDate);
tooltip = tr("Processed %n blocks of transaction history.", "", count);
@@ -722,8 +722,8 @@ void BitcoinGUI::setNumBlocks(int count)
}
else
{
- int years = secs / YEAR_IN_SECONDS;
- int remainder = secs % YEAR_IN_SECONDS;
+ qint64 years = secs / YEAR_IN_SECONDS;
+ qint64 remainder = secs % YEAR_IN_SECONDS;
timeBehindText = tr("%1 and %2").arg(tr("%n year(s)", "", years)).arg(tr("%n week(s)","", remainder/WEEK_IN_SECONDS));
}
diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h
index 3216a7398e..5a289a9046 100644
--- a/src/qt/bitcoingui.h
+++ b/src/qt/bitcoingui.h
@@ -118,7 +118,7 @@ private:
int spinnerFrame;
/** Create the main UI actions. */
- void createActions(const NetworkStyle *networkStyle);
+ void createActions();
/** Create the menu bar and sub-menus. */
void createMenuBar();
/** Create the toolbars */
@@ -143,8 +143,8 @@ signals:
public slots:
/** Set number of connections shown in the UI */
void setNumConnections(int count);
- /** Set number of blocks shown in the UI */
- void setNumBlocks(int count);
+ /** Set number of blocks and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
/** Notify the user of an event from the core network or transaction handling code.
@param[in] title the message box / notification title
diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp
index 03d94f2e13..dc32f81571 100644
--- a/src/qt/clientmodel.cpp
+++ b/src/qt/clientmodel.cpp
@@ -18,7 +18,6 @@
#include <stdint.h>
-#include <QDateTime>
#include <QDebug>
#include <QTimer>
@@ -29,8 +28,10 @@ ClientModel::ClientModel(OptionsModel *optionsModel, QObject *parent) :
optionsModel(optionsModel),
peerTableModel(0),
cachedNumBlocks(0),
- cachedReindexing(0), cachedImporting(0),
- numBlocksAtStartup(-1), pollTimer(0)
+ cachedBlockDate(QDateTime()),
+ cachedReindexing(0),
+ cachedImporting(0),
+ pollTimer(0)
{
peerTableModel = new PeerTableModel(this);
pollTimer = new QTimer(this);
@@ -65,12 +66,6 @@ int ClientModel::getNumBlocks() const
return chainActive.Height();
}
-int ClientModel::getNumBlocksAtStartup()
-{
- if (numBlocksAtStartup == -1) numBlocksAtStartup = getNumBlocks();
- return numBlocksAtStartup;
-}
-
quint64 ClientModel::getTotalBytesRecv() const
{
return CNode::GetTotalBytesRecv();
@@ -84,10 +79,11 @@ quint64 ClientModel::getTotalBytesSent() const
QDateTime ClientModel::getLastBlockDate() const
{
LOCK(cs_main);
+
if (chainActive.Tip())
return QDateTime::fromTime_t(chainActive.Tip()->GetBlockTime());
- else
- return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
+
+ return QDateTime::fromTime_t(Params().GenesisBlock().GetBlockTime()); // Genesis block's time of current network
}
double ClientModel::getVerificationProgress() const
@@ -102,21 +98,26 @@ void ClientModel::updateTimer()
// periodical polls if the core is holding the locks for a longer time -
// for example, during a wallet rescan.
TRY_LOCK(cs_main, lockMain);
- if(!lockMain)
+ if (!lockMain)
return;
+
// Some quantities (such as number of blocks) change so fast that we don't want to be notified for each change.
// Periodically check and update with a timer.
int newNumBlocks = getNumBlocks();
+ QDateTime newBlockDate = getLastBlockDate();
// check for changed number of blocks we have, number of blocks peers claim to have, reindexing state and importing state
if (cachedNumBlocks != newNumBlocks ||
- cachedReindexing != fReindex || cachedImporting != fImporting)
+ cachedBlockDate != newBlockDate ||
+ cachedReindexing != fReindex ||
+ cachedImporting != fImporting)
{
cachedNumBlocks = newNumBlocks;
+ cachedBlockDate = newBlockDate;
cachedReindexing = fReindex;
cachedImporting = fImporting;
- emit numBlocksChanged(newNumBlocks);
+ emit numBlocksChanged(newNumBlocks, newBlockDate);
}
emit bytesChanged(getTotalBytesRecv(), getTotalBytesSent());
diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h
index 4856a72d7d..214701810c 100644
--- a/src/qt/clientmodel.h
+++ b/src/qt/clientmodel.h
@@ -6,6 +6,7 @@
#define BITCOIN_QT_CLIENTMODEL_H
#include <QObject>
+#include <QDateTime>
class AddressTableModel;
class OptionsModel;
@@ -15,7 +16,6 @@ class TransactionTableModel;
class CWallet;
QT_BEGIN_NAMESPACE
-class QDateTime;
class QTimer;
QT_END_NAMESPACE
@@ -48,7 +48,6 @@ public:
//! Return number of connections, default is in- and outbound (total)
int getNumConnections(unsigned int flags = CONNECTIONS_ALL) const;
int getNumBlocks() const;
- int getNumBlocksAtStartup();
quint64 getTotalBytesRecv() const;
quint64 getTotalBytesSent() const;
@@ -74,11 +73,10 @@ private:
PeerTableModel *peerTableModel;
int cachedNumBlocks;
+ QDateTime cachedBlockDate;
bool cachedReindexing;
bool cachedImporting;
- int numBlocksAtStartup;
-
QTimer *pollTimer;
void subscribeToCoreSignals();
@@ -86,7 +84,7 @@ private:
signals:
void numConnectionsChanged(int count);
- void numBlocksChanged(int count);
+ void numBlocksChanged(int count, const QDateTime& blockDate);
void alertsChanged(const QString &warnings);
void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut);
diff --git a/src/qt/forms/helpmessagedialog.ui b/src/qt/forms/helpmessagedialog.ui
index 37008f047e..dc7df9d6c8 100644
--- a/src/qt/forms/helpmessagedialog.ui
+++ b/src/qt/forms/helpmessagedialog.ui
@@ -14,6 +14,69 @@
<string notr="true">Bitcoin Core - Command-line options</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
+ <property name="spacing">
+ <number>0</number>
+ </property>
+ <property name="leftMargin">
+ <number>12</number>
+ </property>
+ <property name="topMargin">
+ <number>12</number>
+ </property>
+ <property name="rightMargin">
+ <number>12</number>
+ </property>
+ <property name="bottomMargin">
+ <number>12</number>
+ </property>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayoutLogo" stretch="0,0">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>4</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="aboutLogo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Ignored">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>100</width>
+ <height>100</height>
+ </size>
+ </property>
+ <property name="pixmap">
+ <pixmap resource="../bitcoin.qrc">:/icons/bitcoin</pixmap>
+ </property>
+ <property name="scaledContents">
+ <bool>true</bool>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QFrame" name="frame">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Raised</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
@@ -25,6 +88,9 @@
</item>
<item>
<widget class="QScrollArea" name="scrollArea">
+ <property name="frameShape">
+ <enum>QFrame::NoFrame</enum>
+ </property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOn</enum>
</property>
@@ -57,6 +123,22 @@
</widget>
</item>
<item>
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Fixed</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>4</width>
+ <height>4</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
<widget class="QDialogButtonBox" name="okButton">
<property name="orientation">
<enum>Qt::Horizontal</enum>
diff --git a/src/qt/forms/sendcoinsdialog.ui b/src/qt/forms/sendcoinsdialog.ui
index eebb459327..b1ed7a27b5 100644
--- a/src/qt/forms/sendcoinsdialog.ui
+++ b/src/qt/forms/sendcoinsdialog.ui
@@ -771,16 +771,6 @@
</property>
</widget>
</item>
- <item>
- <widget class="QPushButton" name="buttonMinimizeFee">
- <property name="toolTip">
- <string>collapse fee-settings</string>
- </property>
- <property name="text">
- <string>Minimize</string>
- </property>
- </widget>
- </item>
</layout>
</item>
<item>
@@ -811,6 +801,16 @@
</property>
</spacer>
</item>
+ <item>
+ <widget class="QPushButton" name="buttonMinimizeFee">
+ <property name="toolTip">
+ <string>collapse fee-settings</string>
+ </property>
+ <property name="text">
+ <string>Minimize</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
<item>
diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp
index 2a13f43ea4..9db0a75971 100644
--- a/src/qt/guiutil.cpp
+++ b/src/qt/guiutil.cpp
@@ -40,6 +40,7 @@
#if BOOST_FILESYSTEM_VERSION >= 3
#include <boost/filesystem/detail/utf8_codecvt_facet.hpp>
#endif
+#include <boost/scoped_array.hpp>
#include <QAbstractItemView>
#include <QApplication>
@@ -567,12 +568,17 @@ TableViewLastColumnResizingFixer::TableViewLastColumnResizingFixer(QTableView* t
#ifdef WIN32
boost::filesystem::path static StartupShortcutPath()
{
+ if (GetBoolArg("-testnet", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (testnet).lnk";
+ else if (GetBoolArg("-regtest", false))
+ return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin (regtest).lnk";
+
return GetSpecialFolderPath(CSIDL_STARTUP) / "Bitcoin.lnk";
}
bool GetStartOnSystemStartup()
{
- // check for Bitcoin.lnk
+ // check for Bitcoin*.lnk
return boost::filesystem::exists(StartupShortcutPath());
}
@@ -588,8 +594,8 @@ bool SetStartOnSystemStartup(bool fAutoStart)
// Get a pointer to the IShellLink interface.
IShellLink* psl = NULL;
HRESULT hres = CoCreateInstance(CLSID_ShellLink, NULL,
- CLSCTX_INPROC_SERVER, IID_IShellLink,
- reinterpret_cast<void**>(&psl));
+ CLSCTX_INPROC_SERVER, IID_IShellLink,
+ reinterpret_cast<void**>(&psl));
if (SUCCEEDED(hres))
{
@@ -597,20 +603,34 @@ bool SetStartOnSystemStartup(bool fAutoStart)
TCHAR pszExePath[MAX_PATH];
GetModuleFileName(NULL, pszExePath, sizeof(pszExePath));
- TCHAR pszArgs[5] = TEXT("-min");
+ // Start client minimized
+ QString strArgs = "-min";
+ // Set -testnet /-regtest options
+ strArgs += QString::fromStdString(strprintf(" -testnet=%d -regtest=%d", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false)));
+
+#ifdef UNICODE
+ boost::scoped_array<TCHAR> args(new TCHAR[strArgs.length() + 1]);
+ // Convert the QString to TCHAR*
+ strArgs.toWCharArray(args.get());
+ // Add missing '\0'-termination to string
+ args[strArgs.length()] = '\0';
+#endif
// Set the path to the shortcut target
psl->SetPath(pszExePath);
PathRemoveFileSpec(pszExePath);
psl->SetWorkingDirectory(pszExePath);
psl->SetShowCmd(SW_SHOWMINNOACTIVE);
- psl->SetArguments(pszArgs);
+#ifndef UNICODE
+ psl->SetArguments(strArgs.toStdString().c_str());
+#else
+ psl->SetArguments(args.get());
+#endif
// Query IShellLink for the IPersistFile interface for
// saving the shortcut in persistent storage.
IPersistFile* ppf = NULL;
- hres = psl->QueryInterface(IID_IPersistFile,
- reinterpret_cast<void**>(&ppf));
+ hres = psl->QueryInterface(IID_IPersistFile, reinterpret_cast<void**>(&ppf));
if (SUCCEEDED(hres))
{
WCHAR pwsz[MAX_PATH];
@@ -630,11 +650,10 @@ bool SetStartOnSystemStartup(bool fAutoStart)
}
return true;
}
-
#elif defined(Q_OS_LINUX)
// Follow the Desktop Application Autostart Spec:
-// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
+// http://standards.freedesktop.org/autostart-spec/autostart-spec-latest.html
boost::filesystem::path static GetAutostartDir()
{
@@ -690,8 +709,13 @@ bool SetStartOnSystemStartup(bool fAutoStart)
// Write a bitcoin.desktop file to the autostart directory:
optionFile << "[Desktop Entry]\n";
optionFile << "Type=Application\n";
- optionFile << "Name=Bitcoin\n";
- optionFile << "Exec=" << pszExePath << " -min\n";
+ if (GetBoolArg("-testnet", false))
+ optionFile << "Name=Bitcoin (testnet)\n";
+ else if (GetBoolArg("-regtest", false))
+ optionFile << "Name=Bitcoin (regtest)\n";
+ else
+ optionFile << "Name=Bitcoin\n";
+ optionFile << "Exec=" << pszExePath << strprintf(" -min -testnet=%d -regtest=%d\n", GetBoolArg("-testnet", false), GetBoolArg("-regtest", false));
optionFile << "Terminal=false\n";
optionFile << "Hidden=false\n";
optionFile.close();
diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp
index a0f3993e69..a342b4bfea 100644
--- a/src/qt/optionsdialog.cpp
+++ b/src/qt/optionsdialog.cpp
@@ -38,7 +38,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
fProxyIpValid(true)
{
ui->setupUi(this);
- GUIUtil::restoreWindowGeometry("nOptionsDialogWindow", this->size(), this);
/* Main elements init */
ui->databaseCache->setMinimum(nMinDbCache);
@@ -117,7 +116,6 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
OptionsDialog::~OptionsDialog()
{
- GUIUtil::saveWindowGeometry("nOptionsDialogWindow", this);
delete ui;
}
diff --git a/src/qt/paymentrequestplus.cpp b/src/qt/paymentrequestplus.cpp
index 4c1e898020..b69461ad9e 100644
--- a/src/qt/paymentrequestplus.cpp
+++ b/src/qt/paymentrequestplus.cpp
@@ -13,7 +13,6 @@
#include <stdexcept>
-#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <QDateTime>
diff --git a/src/qt/paymentrequestplus.h b/src/qt/paymentrequestplus.h
index fbc3a09265..61f8a3415d 100644
--- a/src/qt/paymentrequestplus.h
+++ b/src/qt/paymentrequestplus.h
@@ -9,6 +9,8 @@
#include "base58.h"
+#include <openssl/x509.h>
+
#include <QByteArray>
#include <QList>
#include <QString>
diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp
index a00916bf7f..96ceeb18a4 100644
--- a/src/qt/paymentserver.cpp
+++ b/src/qt/paymentserver.cpp
@@ -16,7 +16,6 @@
#include <cstdlib>
-#include <openssl/x509.h>
#include <openssl/x509_vfy.h>
#include <QApplication>
@@ -569,6 +568,14 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
return false;
}
+ // Bitcoin amounts are stored as (optional) uint64 in the protobuf messages (see paymentrequest.proto),
+ // but CAmount is defined as int64_t. Because of that we need to verify that amounts are in a valid range
+ // and no overflow has happened.
+ if (!verifyAmount(sendingTo.second)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
+
// Extract and check amounts
CTxOut txOut(sendingTo.second, sendingTo.first);
if (txOut.IsDust(::minRelayTxFee)) {
@@ -580,6 +587,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
}
recipient.amount += sendingTo.second;
+ // Also verify that the final amount is still in a valid range after adding additional amounts.
+ if (!verifyAmount(recipient.amount)) {
+ emit message(tr("Payment request rejected"), tr("Invalid payment request."), CClientUIInterface::MSG_ERROR);
+ return false;
+ }
}
// Store addresses and format them to fit nicely into the GUI
recipient.address = addresses.join("<br />");
@@ -768,3 +780,15 @@ bool PaymentServer::verifyExpired(const payments::PaymentDetails& requestDetails
}
return fVerified;
}
+
+bool PaymentServer::verifyAmount(const CAmount& requestAmount)
+{
+ bool fVerified = MoneyRange(requestAmount);
+ if (!fVerified) {
+ qWarning() << QString("PaymentServer::%1: Payment request amount out of allowed range (%2, allowed 0 - %3).")
+ .arg(__func__)
+ .arg(requestAmount)
+ .arg(MAX_MONEY);
+ }
+ return fVerified;
+}
diff --git a/src/qt/paymentserver.h b/src/qt/paymentserver.h
index db5f44ff1d..6bf5ac2eea 100644
--- a/src/qt/paymentserver.h
+++ b/src/qt/paymentserver.h
@@ -95,6 +95,8 @@ public:
static bool verifyNetwork(const payments::PaymentDetails& requestDetails);
// Verify if the payment request is expired
static bool verifyExpired(const payments::PaymentDetails& requestDetails);
+ // Verify the payment request amount is valid
+ static bool verifyAmount(const CAmount& requestAmount);
signals:
// Fired when a valid payment request is received
diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp
index 9f3991c4c5..ccde44fb29 100644
--- a/src/qt/rpcconsole.cpp
+++ b/src/qt/rpcconsole.cpp
@@ -293,8 +293,8 @@ void RPCConsole::setClientModel(ClientModel *model)
setNumConnections(model->getNumConnections());
connect(model, SIGNAL(numConnectionsChanged(int)), this, SLOT(setNumConnections(int)));
- setNumBlocks(model->getNumBlocks());
- connect(model, SIGNAL(numBlocksChanged(int)), this, SLOT(setNumBlocks(int)));
+ setNumBlocks(model->getNumBlocks(), model->getLastBlockDate());
+ connect(model, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(setNumBlocks(int,QDateTime)));
updateTrafficStats(model->getTotalBytesRecv(), model->getTotalBytesSent());
connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64)));
@@ -404,11 +404,10 @@ void RPCConsole::setNumConnections(int count)
ui->numberOfConnections->setText(connections);
}
-void RPCConsole::setNumBlocks(int count)
+void RPCConsole::setNumBlocks(int count, const QDateTime& blockDate)
{
ui->numberOfBlocks->setText(QString::number(count));
- if(clientModel)
- ui->lastBlockTime->setText(clientModel->getLastBlockDate().toString());
+ ui->lastBlockTime->setText(blockDate.toString());
}
void RPCConsole::on_lineEdit_returnPressed()
diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h
index fff5cfbf59..8737be35d1 100644
--- a/src/qt/rpcconsole.h
+++ b/src/qt/rpcconsole.h
@@ -63,8 +63,8 @@ public slots:
void message(int category, const QString &message, bool html = false);
/** Set number of connections shown in the UI */
void setNumConnections(int count);
- /** Set number of blocks shown in the UI */
- void setNumBlocks(int count);
+ /** Set number of blocks and last block date shown in the UI */
+ void setNumBlocks(int count, const QDateTime& blockDate);
/** Go forward or back in history */
void browseHistory(int offset);
/** Scroll console view to end */
diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp
index 5aef2d7539..4f3230a8c9 100644
--- a/src/qt/sendcoinsdialog.cpp
+++ b/src/qt/sendcoinsdialog.cpp
@@ -121,7 +121,7 @@ void SendCoinsDialog::setClientModel(ClientModel *clientModel)
this->clientModel = clientModel;
if (clientModel) {
- connect(clientModel, SIGNAL(numBlocksChanged(int)), this, SLOT(updateSmartFeeLabel()));
+ connect(clientModel, SIGNAL(numBlocksChanged(int,QDateTime)), this, SLOT(updateSmartFeeLabel()));
}
}
diff --git a/src/qt/test/paymentrequestdata.h b/src/qt/test/paymentrequestdata.h
index 50636d7c67..c548ffe429 100644
--- a/src/qt/test/paymentrequestdata.h
+++ b/src/qt/test/paymentrequestdata.h
@@ -433,3 +433,28 @@ dGluZyB0ZXN0bmV0ISqAAXSQG8+GFA18VaKarlYrOz293rNMIub0swKGcQm8jAGX\
HSLaRgHfUDeEPr4hydy4dtfu59KNwe2xsHOHu/SpO4L8SrA4Dm9A7SlNBVWdcLbw\
d2hj739GDLz0b5KuJ2SG6VknMRQM976w/m2qlq0ccVGaaZ2zMIGfpzL3p6adwx/5\
";
+
+//
+// Payment request with amount overflow (amount is set to 21000001 BTC)
+//
+const char* paymentrequest5_cert2_BASE64 =
+"\
+Egt4NTA5K3NoYTI1NhrQBArNBDCCAkkwggExoAMCAQICAQEwDQYJKoZIhvcNAQEL\
+BQAwITEfMB0GA1UEAwwWUGF5bWVudFJlcXVlc3QgVGVzdCBDQTAeFw0xNTAxMTEx\
+ODIxMDhaFw0yNTAxMDgxODIxMDhaMCExHzAdBgNVBAMMFlBheW1lbnRSZXF1ZXN0\
+IFRlc3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMsZqzkzeBGo+i2N\
+mUak3Ciodr1V7S062VOy7N0OQYNDQHYkgDFAUET7cEb5VJaHPv5m3ppTBpU9xBcf\
+wbHHUt4VjA+mhRmYrl1khjvZM+X8kEqvWn20BtcM9R6r0yIYec8UERDDHBleL/P8\
+RkxEnVLjYTV9zigCXfMsgYb3EQShAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ\
+KoZIhvcNAQELBQADggEBABUJpl3QCqsoDSxAsQdV6zKT4VGV76AzoGj7etQsQY+r\
++S26VfWh/fMobEzuxFChr0USgLJ6FoK78hAtoZvt1lrye9yqFv/ig3WLWsJKWHHb\
+3RT6oR03CIwZXFSUasi08QDVLxafwsU5OMcPLucF3a1lRL1ccYrNgVCCx1+X7Bos\
+tIgDGRQQ4AyoHTcfVd2hEGeUv7k14mOxFsAp6851yosHq9Q2kwmdH+rHEJbjof87\
+yyKLagc4owyXBZYkQmkeHWCNqnuRmO5vUsfVb0UUrkD64o7Th/NjwooA7SCiUXl6\
+dfygT1b7ggpx7GC+sP2DsIM47IAZ55drjqX5u2f+Ba0iTAoEdGVzdBIkCIDC9P+F\
+vt0DEhl2qRQErGqUUwSsaMpDvWIaGnJGNQqi8oisGLzcrKYFKhhUZXN0aW5nIGFt\
+b3VudCBvdmVyZmxvdyEqgAG8S7WEDUC6tCL6q2CTBjop/AitgEy31RL9IqYruytR\
+iEBFUrBDJZU+UEezGwr7/zoECjo5ZY3PmtZcM2sILNjyweJF6XVzGqTxUw6pN6sW\
+XR2T3Gy2LzRvhVA25QgGqpz0/juS2BtmNbsZPkN9gMMwKimgzc+PuCzmEKwPK9cQ\
+YQ==\
+";
diff --git a/src/qt/test/paymentservertests.cpp b/src/qt/test/paymentservertests.cpp
index 04935192c8..e2ec439b2e 100644
--- a/src/qt/test/paymentservertests.cpp
+++ b/src/qt/test/paymentservertests.cpp
@@ -7,7 +7,10 @@
#include "optionsmodel.h"
#include "paymentrequestdata.h"
+#include "amount.h"
#include "random.h"
+#include "script/script.h"
+#include "script/standard.h"
#include "util.h"
#include "utilstrencodings.h"
@@ -184,6 +187,20 @@ void PaymentServerTests::paymentServerTests()
tempFile.close();
QCOMPARE(PaymentServer::readPaymentRequestFromFile(tempFile.fileName(), r.paymentRequest), false);
+ // Payment request with amount overflow (amount is set to 21000001 BTC):
+ data = DecodeBase64(paymentrequest5_cert2_BASE64);
+ byteArray = QByteArray((const char*)&data[0], data.size());
+ r.paymentRequest.parse(byteArray);
+ // Ensure the request is initialized
+ QVERIFY(r.paymentRequest.IsInitialized());
+ // Extract address and amount from the request
+ QList<std::pair<CScript, CAmount> > sendingTos = r.paymentRequest.getPayTo();
+ foreach (const PAIRTYPE(CScript, CAmount)& sendingTo, sendingTos) {
+ CTxDestination dest;
+ if (ExtractDestination(sendingTo.first, dest))
+ QCOMPARE(PaymentServer::verifyAmount(sendingTo.second), false);
+ }
+
delete server;
}
diff --git a/src/qt/utilitydialog.cpp b/src/qt/utilitydialog.cpp
index 4ef42b927e..4e7b70efe6 100644
--- a/src/qt/utilitydialog.cpp
+++ b/src/qt/utilitydialog.cpp
@@ -29,7 +29,6 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
ui(new Ui::HelpMessageDialog)
{
ui->setupUi(this);
- GUIUtil::restoreWindowGeometry("nHelpMessageDialogWindow", this->size(), this);
QString version = tr("Bitcoin Core") + " " + tr("version") + " " + QString::fromStdString(FormatFullVersion());
/* On x86 add a bit specifier to the version so that users can distinguish between
@@ -137,12 +136,12 @@ HelpMessageDialog::HelpMessageDialog(QWidget *parent, bool about) :
ui->helpMessage->moveCursor(QTextCursor::Start);
ui->scrollArea->setVisible(false);
+ ui->aboutLogo->setVisible(false);
}
}
HelpMessageDialog::~HelpMessageDialog()
{
- GUIUtil::saveWindowGeometry("nHelpMessageDialogWindow", this);
delete ui;
}
diff --git a/src/random.cpp b/src/random.cpp
index 663456e962..0ba0de908d 100644
--- a/src/random.cpp
+++ b/src/random.cpp
@@ -5,6 +5,7 @@
#include "random.h"
+#include "support/cleanse.h"
#ifdef WIN32
#include "compat.h" // for Windows API
#endif
@@ -18,7 +19,6 @@
#include <sys/time.h>
#endif
-#include <openssl/crypto.h>
#include <openssl/err.h>
#include <openssl/rand.h>
@@ -40,22 +40,23 @@ void RandAddSeed()
// Seed with CPU performance counter
int64_t nCounter = GetPerformanceCounter();
RAND_add(&nCounter, sizeof(nCounter), 1.5);
- OPENSSL_cleanse((void*)&nCounter, sizeof(nCounter));
+ memory_cleanse((void*)&nCounter, sizeof(nCounter));
}
void RandAddSeedPerfmon()
{
RandAddSeed();
+#ifdef WIN32
+ // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
+ // Seed with the entire set of perfmon data
+
// This can take up to 2 seconds, so only do it every 10 minutes
static int64_t nLastPerfmon;
if (GetTime() < nLastPerfmon + 10 * 60)
return;
nLastPerfmon = GetTime();
-#ifdef WIN32
- // Don't need this on Linux, OpenSSL automatically uses /dev/urandom
- // Seed with the entire set of perfmon data
std::vector<unsigned char> vData(250000, 0);
long ret = 0;
unsigned long nSize = 0;
@@ -70,7 +71,7 @@ void RandAddSeedPerfmon()
RegCloseKey(HKEY_PERFORMANCE_DATA);
if (ret == ERROR_SUCCESS) {
RAND_add(begin_ptr(vData), nSize, nSize / 100.0);
- OPENSSL_cleanse(begin_ptr(vData), nSize);
+ memory_cleanse(begin_ptr(vData), nSize);
LogPrint("rand", "%s: %lu bytes\n", __func__, nSize);
} else {
static bool warned = false; // Warn only once
diff --git a/src/rest.cpp b/src/rest.cpp
index 1ee1d52912..adc2d56284 100644
--- a/src/rest.cpp
+++ b/src/rest.cpp
@@ -95,7 +95,7 @@ static bool rest_headers(AcceptedConnection* conn,
bool fRun)
{
vector<string> params;
- enum RetFormat rf = ParseDataFormat(params, strReq);
+ const RetFormat rf = ParseDataFormat(params, strReq);
vector<string> path;
boost::split(path, params[0], boost::is_any_of("/"));
@@ -159,7 +159,7 @@ static bool rest_block(AcceptedConnection* conn,
bool showTxDetails)
{
vector<string> params;
- enum RetFormat rf = ParseDataFormat(params, strReq);
+ const RetFormat rf = ParseDataFormat(params, strReq);
string hashStr = params[0];
uint256 hash;
@@ -226,13 +226,39 @@ static bool rest_block_notxdetails(AcceptedConnection* conn,
return rest_block(conn, strReq, mapHeaders, fRun, false);
}
+static bool rest_chaininfo(AcceptedConnection* conn,
+ const std::string& strReq,
+ const std::map<std::string, std::string>& mapHeaders,
+ bool fRun)
+{
+ vector<string> params;
+ const RetFormat rf = ParseDataFormat(params, strReq);
+
+ switch (rf) {
+ case RF_JSON: {
+ Array rpcParams;
+ Value chainInfoObject = getblockchaininfo(rpcParams, false);
+
+ string strJSON = write_string(chainInfoObject, false) + "\n";
+ conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush;
+ return true;
+ }
+ default: {
+ throw RESTERR(HTTP_NOT_FOUND, "output format not found (available: json)");
+ }
+ }
+
+ // not reached
+ return true; // continue to process further HTTP reqs on this cxn
+}
+
static bool rest_tx(AcceptedConnection* conn,
const std::string& strReq,
const std::map<std::string, std::string>& mapHeaders,
bool fRun)
{
vector<string> params;
- enum RetFormat rf = ParseDataFormat(params, strReq);
+ const RetFormat rf = ParseDataFormat(params, strReq);
string hashStr = params[0];
uint256 hash;
@@ -287,6 +313,7 @@ static const struct {
{"/rest/tx/", rest_tx},
{"/rest/block/notxdetails/", rest_block_notxdetails},
{"/rest/block/", rest_block_extended},
+ {"/rest/chaininfo", rest_chaininfo},
{"/rest/headers/", rest_headers},
};
diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp
index 8f2d34edff..165a9df697 100644
--- a/src/rpcmining.cpp
+++ b/src/rpcmining.cpp
@@ -44,7 +44,7 @@ Value GetNetworkHashPS(int lookup, int height) {
// If lookup is -1, then use blocks since last difficulty change.
if (lookup <= 0)
- lookup = pb->nHeight % 2016 + 1;
+ lookup = pb->nHeight % Params().DifficultyAdjustmentInterval() + 1;
// If lookup is larger than chain, then set it to chain length.
if (lookup > pb->nHeight)
diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp
index 8d260b1cc9..2eda4d3355 100644
--- a/src/rpcmisc.cpp
+++ b/src/rpcmisc.cpp
@@ -228,6 +228,8 @@ CScript _createmultisig_redeemScript(const Array& params)
throw runtime_error(
strprintf("not enough keys supplied "
"(got %u keys, but need at least %d to redeem)", keys.size(), nRequired));
+ if (keys.size() > 16)
+ throw runtime_error("Number of addresses involved in the multisignature address creation > 16\nReduce the number");
std::vector<CPubKey> pubkeys;
pubkeys.resize(keys.size());
for (unsigned int i = 0; i < keys.size(); i++)
diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp
index 823b1fcf24..20e9252d7e 100644
--- a/src/rpcserver.cpp
+++ b/src/rpcserver.cpp
@@ -849,7 +849,7 @@ void JSONRequest::parse(const Value& valRequest)
throw JSONRPCError(RPC_INVALID_REQUEST, "Method must be a string");
strMethod = valMethod.get_str();
if (strMethod != "getblocktemplate")
- LogPrint("rpc", "ThreadRPCServer method=%s\n", strMethod);
+ LogPrint("rpc", "ThreadRPCServer method=%s\n", SanitizeString(strMethod));
// Parse params
Value valParams = find_value(request, "params");
diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp
index 1afc3c910e..d097b6a0fa 100644
--- a/src/rpcwallet.cpp
+++ b/src/rpcwallet.cpp
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <boost/assign/list_of.hpp>
+
#include "json/json_spirit_utils.h"
#include "json/json_spirit_value.h"
@@ -316,35 +317,29 @@ Value getaddressesbyaccount(const Array& params, bool fHelp)
return ret;
}
-void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
+static void SendMoney(const CTxDestination &address, CAmount nValue, CWalletTx& wtxNew)
{
+ CAmount curBalance = pwalletMain->GetBalance();
+
// Check amount
if (nValue <= 0)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid amount");
- if (nValue > pwalletMain->GetBalance())
+ if (nValue > curBalance)
throw JSONRPCError(RPC_WALLET_INSUFFICIENT_FUNDS, "Insufficient funds");
- string strError;
- if (pwalletMain->IsLocked())
- {
- strError = "Error: Wallet locked, unable to create transaction!";
- LogPrintf("SendMoney(): %s", strError);
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
- }
-
// Parse Bitcoin address
CScript scriptPubKey = GetScriptForDestination(address);
// Create and send the transaction
CReserveKey reservekey(pwalletMain);
CAmount nFeeRequired;
- if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError))
- {
- if (nValue + nFeeRequired > pwalletMain->GetBalance())
- strError = strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired));
- LogPrintf("SendMoney(): %s\n", strError);
- throw JSONRPCError(RPC_WALLET_ERROR, strError);
+ std::string strError;
+ if (!pwalletMain->CreateTransaction(scriptPubKey, nValue, wtxNew, reservekey, nFeeRequired, strError)) {
+ if (nValue + nFeeRequired > curBalance)
+ throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Error: This transaction requires a transaction fee of at least %s because of its amount, complexity, or use of recently received funds!", FormatMoney(nFeeRequired)));
+ else
+ throw JSONRPCError(RPC_WALLET_ERROR, strError);
}
if (!pwalletMain->CommitTransaction(wtxNew, reservekey))
throw JSONRPCError(RPC_WALLET_ERROR, "Error: The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
diff --git a/src/script/script.h b/src/script/script.h
index 8b36aa2f50..ed456f5c5a 100644
--- a/src/script/script.h
+++ b/src/script/script.h
@@ -14,6 +14,7 @@
#include <string.h>
#include <string>
#include <vector>
+#include "crypto/common.h"
static const unsigned int MAX_SCRIPT_ELEMENT_SIZE = 520; // bytes
@@ -416,14 +417,16 @@ public:
else if (b.size() <= 0xffff)
{
insert(end(), OP_PUSHDATA2);
- unsigned short nSize = b.size();
- insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
+ uint8_t data[2];
+ WriteLE16(data, b.size());
+ insert(end(), data, data + sizeof(data));
}
else
{
insert(end(), OP_PUSHDATA4);
- unsigned int nSize = b.size();
- insert(end(), (unsigned char*)&nSize, (unsigned char*)&nSize + sizeof(nSize));
+ uint8_t data[4];
+ WriteLE32(data, b.size());
+ insert(end(), data, data + sizeof(data));
}
insert(end(), b.begin(), b.end());
return *this;
@@ -496,15 +499,14 @@ public:
{
if (end() - pc < 2)
return false;
- nSize = 0;
- memcpy(&nSize, &pc[0], 2);
+ nSize = ReadLE16(&pc[0]);
pc += 2;
}
else if (opcode == OP_PUSHDATA4)
{
if (end() - pc < 4)
return false;
- memcpy(&nSize, &pc[0], 4);
+ nSize = ReadLE32(&pc[0]);
pc += 4;
}
if (end() - pc < 0 || (unsigned int)(end() - pc) < nSize)
diff --git a/src/serialize.h b/src/serialize.h
index a62760a793..741f78f8b4 100644
--- a/src/serialize.h
+++ b/src/serialize.h
@@ -18,6 +18,8 @@
#include <utility>
#include <vector>
+#include "compat/endian.h"
+
class CScript;
static const unsigned int MAX_SIZE = 0x02000000;
@@ -71,6 +73,79 @@ inline const T* end_ptr(const std::vector<T,TAl>& v)
return v.empty() ? NULL : (&v[0] + v.size());
}
+/*
+ * Lowest-level serialization and conversion.
+ * @note Sizes of these types are verified in the tests
+ */
+template<typename Stream> inline void ser_writedata8(Stream &s, uint8_t obj)
+{
+ s.write((char*)&obj, 1);
+}
+template<typename Stream> inline void ser_writedata16(Stream &s, uint16_t obj)
+{
+ obj = htole16(obj);
+ s.write((char*)&obj, 2);
+}
+template<typename Stream> inline void ser_writedata32(Stream &s, uint32_t obj)
+{
+ obj = htole32(obj);
+ s.write((char*)&obj, 4);
+}
+template<typename Stream> inline void ser_writedata64(Stream &s, uint64_t obj)
+{
+ obj = htole64(obj);
+ s.write((char*)&obj, 8);
+}
+template<typename Stream> inline uint8_t ser_readdata8(Stream &s)
+{
+ uint8_t obj;
+ s.read((char*)&obj, 1);
+ return obj;
+}
+template<typename Stream> inline uint16_t ser_readdata16(Stream &s)
+{
+ uint16_t obj;
+ s.read((char*)&obj, 2);
+ return le16toh(obj);
+}
+template<typename Stream> inline uint32_t ser_readdata32(Stream &s)
+{
+ uint32_t obj;
+ s.read((char*)&obj, 4);
+ return le32toh(obj);
+}
+template<typename Stream> inline uint64_t ser_readdata64(Stream &s)
+{
+ uint64_t obj;
+ s.read((char*)&obj, 8);
+ return le64toh(obj);
+}
+inline uint64_t ser_double_to_uint64(double x)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline uint32_t ser_float_to_uint32(float x)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.x = x;
+ return tmp.y;
+}
+inline double ser_uint64_to_double(uint64_t y)
+{
+ union { double x; uint64_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+inline float ser_uint32_to_float(uint32_t y)
+{
+ union { float x; uint32_t y; } tmp;
+ tmp.y = y;
+ return tmp.x;
+}
+
+
/////////////////////////////////////////////////////////////////
//
// Templates for serializing to anything that looks like a stream,
@@ -108,59 +183,48 @@ enum
SerializationOp(s, CSerActionUnserialize(), nType, nVersion); \
}
-
-
/*
* Basic Types
*/
-#define WRITEDATA(s, obj) s.write((char*)&(obj), sizeof(obj))
-#define READDATA(s, obj) s.read((char*)&(obj), sizeof(obj))
-
-inline unsigned int GetSerializeSize(char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned char a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned short a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned int a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(signed long long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(unsigned long long a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(float a, int, int=0) { return sizeof(a); }
-inline unsigned int GetSerializeSize(double a, int, int=0) { return sizeof(a); }
-
-template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned char a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned short a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned int a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, signed long long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, unsigned long long a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { WRITEDATA(s, a); }
-template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { WRITEDATA(s, a); }
-
-template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned char& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned short& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned int& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, signed long long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, unsigned long long& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { READDATA(s, a); }
-template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { READDATA(s, a); }
+inline unsigned int GetSerializeSize(char a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(uint8_t a, int, int=0) { return 1; }
+inline unsigned int GetSerializeSize(int16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(uint16_t a, int, int=0) { return 2; }
+inline unsigned int GetSerializeSize(int32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(uint32_t a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(int64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(uint64_t a, int, int=0) { return 8; }
+inline unsigned int GetSerializeSize(float a, int, int=0) { return 4; }
+inline unsigned int GetSerializeSize(double a, int, int=0) { return 8; }
+
+template<typename Stream> inline void Serialize(Stream& s, char a, int, int=0) { ser_writedata8(s, a); } // TODO Get rid of bare char
+template<typename Stream> inline void Serialize(Stream& s, int8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint8_t a, int, int=0) { ser_writedata8(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint16_t a, int, int=0) { ser_writedata16(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint32_t a, int, int=0) { ser_writedata32(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, int64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, uint64_t a, int, int=0) { ser_writedata64(s, a); }
+template<typename Stream> inline void Serialize(Stream& s, float a, int, int=0) { ser_writedata32(s, ser_float_to_uint32(a)); }
+template<typename Stream> inline void Serialize(Stream& s, double a, int, int=0) { ser_writedata64(s, ser_double_to_uint64(a)); }
+
+template<typename Stream> inline void Unserialize(Stream& s, char& a, int, int=0) { a = ser_readdata8(s); } // TODO Get rid of bare char
+template<typename Stream> inline void Unserialize(Stream& s, int8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint8_t& a, int, int=0) { a = ser_readdata8(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint16_t& a, int, int=0) { a = ser_readdata16(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint32_t& a, int, int=0) { a = ser_readdata32(s); }
+template<typename Stream> inline void Unserialize(Stream& s, int64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, uint64_t& a, int, int=0) { a = ser_readdata64(s); }
+template<typename Stream> inline void Unserialize(Stream& s, float& a, int, int=0) { a = ser_uint32_to_float(ser_readdata32(s)); }
+template<typename Stream> inline void Unserialize(Stream& s, double& a, int, int=0) { a = ser_uint64_to_double(ser_readdata64(s)); }
inline unsigned int GetSerializeSize(bool a, int, int=0) { return sizeof(char); }
-template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; WRITEDATA(s, f); }
-template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f; READDATA(s, f); a=f; }
+template<typename Stream> inline void Serialize(Stream& s, bool a, int, int=0) { char f=a; ser_writedata8(s, f); }
+template<typename Stream> inline void Unserialize(Stream& s, bool& a, int, int=0) { char f=ser_readdata8(s); a=f; }
@@ -187,29 +251,22 @@ void WriteCompactSize(Stream& os, uint64_t nSize)
{
if (nSize < 253)
{
- unsigned char chSize = nSize;
- WRITEDATA(os, chSize);
+ ser_writedata8(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned short>::max())
{
- unsigned char chSize = 253;
- unsigned short xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 253);
+ ser_writedata16(os, nSize);
}
else if (nSize <= std::numeric_limits<unsigned int>::max())
{
- unsigned char chSize = 254;
- unsigned int xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 254);
+ ser_writedata32(os, nSize);
}
else
{
- unsigned char chSize = 255;
- uint64_t xSize = nSize;
- WRITEDATA(os, chSize);
- WRITEDATA(os, xSize);
+ ser_writedata8(os, 255);
+ ser_writedata64(os, nSize);
}
return;
}
@@ -217,8 +274,7 @@ void WriteCompactSize(Stream& os, uint64_t nSize)
template<typename Stream>
uint64_t ReadCompactSize(Stream& is)
{
- unsigned char chSize;
- READDATA(is, chSize);
+ uint8_t chSize = ser_readdata8(is);
uint64_t nSizeRet = 0;
if (chSize < 253)
{
@@ -226,25 +282,19 @@ uint64_t ReadCompactSize(Stream& is)
}
else if (chSize == 253)
{
- unsigned short xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata16(is);
if (nSizeRet < 253)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else if (chSize == 254)
{
- unsigned int xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata32(is);
if (nSizeRet < 0x10000u)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
else
{
- uint64_t xSize;
- READDATA(is, xSize);
- nSizeRet = xSize;
+ nSizeRet = ser_readdata64(is);
if (nSizeRet < 0x100000000ULL)
throw std::ios_base::failure("non-canonical ReadCompactSize()");
}
@@ -303,7 +353,7 @@ void WriteVarInt(Stream& os, I n)
len++;
}
do {
- WRITEDATA(os, tmp[len]);
+ ser_writedata8(os, tmp[len]);
} while(len--);
}
@@ -312,8 +362,7 @@ I ReadVarInt(Stream& is)
{
I n = 0;
while(true) {
- unsigned char chData;
- READDATA(is, chData);
+ unsigned char chData = ser_readdata8(is);
n = (n << 7) | (chData & 0x7F);
if (chData & 0x80)
n++;
diff --git a/src/streams.h b/src/streams.h
index bd8568b1af..9999c2341f 100644
--- a/src/streams.h
+++ b/src/streams.h
@@ -16,6 +16,7 @@
#include <map>
#include <set>
#include <stdint.h>
+#include <stdio.h>
#include <string>
#include <string.h>
#include <utility>
diff --git a/src/support/cleanse.cpp b/src/support/cleanse.cpp
new file mode 100644
index 0000000000..a2141b2449
--- /dev/null
+++ b/src/support/cleanse.cpp
@@ -0,0 +1,13 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "cleanse.h"
+
+#include <openssl/crypto.h>
+
+void memory_cleanse(void *ptr, size_t len)
+{
+ OPENSSL_cleanse(ptr, len);
+}
diff --git a/src/support/cleanse.h b/src/support/cleanse.h
new file mode 100644
index 0000000000..3e02aa8fd1
--- /dev/null
+++ b/src/support/cleanse.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2009-2010 Satoshi Nakamoto
+// Copyright (c) 2009-2015 The Bitcoin Core developers
+// Distributed under the MIT software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#ifndef BITCOIN_SUPPORT_CLEANSE_H
+#define BITCOIN_SUPPORT_CLEANSE_H
+
+#include <stdlib.h>
+
+void memory_cleanse(void *ptr, size_t len);
+
+#endif // BITCOIN_SUPPORT_CLEANSE_H
diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json
index a67c157aff..3c52547a64 100644
--- a/src/test/data/script_invalid.json
+++ b/src/test/data/script_invalid.json
@@ -696,7 +696,13 @@
"BIP66 example 11, with DERSIG"
],
[
- "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101",
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "DERSIG",
+ "P2PK with multi-byte hashtype, with DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"LOW_S",
"P2PK with high S"
diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json
index fb81fcb1f5..34e2c8d61a 100644
--- a/src/test/data/script_valid.json
+++ b/src/test/data/script_valid.json
@@ -814,7 +814,13 @@
"BIP66 example 12, with DERSIG"
],
[
- "0x49 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef05101",
+ "0x48 0x304402203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022054e1c258c2981cdfba5df1f46661fb6541c44f77ca0092f3600331abfffb12510101",
+ "0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
+ "",
+ "P2PK with multi-byte hashtype, without DERSIG"
+],
+[
+ "0x48 0x304502203e4516da7253cf068effec6b95c41221c0cf3a8e6ccb8cbf1725b562e9afde2c022100ab1e3da73d67e32045a20e0b999e049978ea8d6ee5480d485fcf2ce0d03b2ef001",
"0x21 0x03363d90d447b00c9c99ceac05b6262ee053441c7e55552ffe526bad8f83ff4640 CHECKSIG",
"",
"P2PK with high S but no LOW_S"
diff --git a/src/test/pow_tests.cpp b/src/test/pow_tests.cpp
new file mode 100644
index 0000000000..e42c1b0a8b
--- /dev/null
+++ b/src/test/pow_tests.cpp
@@ -0,0 +1,66 @@
+// Copyright (c) 2015 The Bitcoin Core developers
+// Distributed under the MIT/X11 software license, see the accompanying
+// file COPYING or http://www.opensource.org/licenses/mit-license.php.
+
+#include "main.h"
+#include "pow.h"
+#include "util.h"
+
+#include <boost/test/unit_test.hpp>
+
+using namespace std;
+
+BOOST_AUTO_TEST_SUITE(pow_tests)
+
+/* Test calculation of next difficulty target with no constraints applying */
+BOOST_AUTO_TEST_CASE(get_next_work)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1261130161; // Block #30240
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 32255;
+ pindexLast.nTime = 1262152739; // Block #32255
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00d86a);
+}
+
+/* Test the constraint on the upper bound for next work */
+BOOST_AUTO_TEST_CASE(get_next_work_pow_limit)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1231006505; // Block #0
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 2015;
+ pindexLast.nTime = 1233061996; // Block #2015
+ pindexLast.nBits = 0x1d00ffff;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00ffff);
+}
+
+/* Test the constraint on the lower bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_lower_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+
+ int64_t nLastRetargetTime = 1279008237; // Block #66528
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 68543;
+ pindexLast.nTime = 1279297671; // Block #68543
+ pindexLast.nBits = 0x1c05a3f4;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1c0168fd);
+}
+
+/* Test the constraint on the upper bound for actual time taken */
+BOOST_AUTO_TEST_CASE(get_next_work_upper_limit_actual)
+{
+ SelectParams(CBaseChainParams::MAIN);
+ int64_t nLastRetargetTime = 1263163443; // NOTE: Not an actual block time
+ CBlockIndex pindexLast;
+ pindexLast.nHeight = 46367;
+ pindexLast.nTime = 1269211443; // Block #46367
+ pindexLast.nBits = 0x1c387f6f;
+ BOOST_CHECK_EQUAL(CalculateNextWorkRequired(&pindexLast, nLastRetargetTime), 0x1d00e1fd);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp
index 6092afd782..e410b59710 100644
--- a/src/test/script_tests.cpp
+++ b/src/test/script_tests.cpp
@@ -107,7 +107,6 @@ void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
std::vector<unsigned char> r, s;
r = std::vector<unsigned char>(vchSig.begin() + 4, vchSig.begin() + 4 + vchSig[3]);
s = std::vector<unsigned char>(vchSig.begin() + 6 + vchSig[3], vchSig.begin() + 6 + vchSig[3] + vchSig[5 + vchSig[3]]);
- unsigned char hashtype = vchSig.back();
// Really ugly to implement mod-n negation here, but it would be feature creep to expose such functionality from libsecp256k1.
static const unsigned char order[33] = {
@@ -141,7 +140,6 @@ void static NegateSignatureS(std::vector<unsigned char>& vchSig) {
vchSig.push_back(0x02);
vchSig.push_back(s.size());
vchSig.insert(vchSig.end(), s.begin(), s.end());
- vchSig.push_back(hashtype);
}
namespace
@@ -478,6 +476,12 @@ BOOST_AUTO_TEST_CASE(script_build)
good.push_back(TestBuilder(CScript() << OP_2 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey2C) << OP_2 << OP_CHECKMULTISIG << OP_NOT,
"BIP66 example 12, with DERSIG", SCRIPT_VERIFY_DERSIG
).Num(0).PushSig(keys.key1, SIGHASH_ALL, 33, 32).EditPush(1, "45022100", "440220").Num(0));
+ good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, without DERSIG", 0
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
+ bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
+ "P2PK with multi-byte hashtype, with DERSIG", SCRIPT_VERIFY_DERSIG
+ ).PushSig(keys.key2, SIGHASH_ALL).EditPush(70, "01", "0101"));
good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey2C) << OP_CHECKSIG,
"P2PK with high S but no LOW_S", 0
diff --git a/src/test/serialize_tests.cpp b/src/test/serialize_tests.cpp
index fe49af711b..de9510d54a 100644
--- a/src/test/serialize_tests.cpp
+++ b/src/test/serialize_tests.cpp
@@ -4,6 +4,7 @@
#include "serialize.h"
#include "streams.h"
+#include "hash.h"
#include <stdint.h>
@@ -13,6 +14,119 @@ using namespace std;
BOOST_AUTO_TEST_SUITE(serialize_tests)
+BOOST_AUTO_TEST_CASE(sizes)
+{
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(char(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int8_t), GetSerializeSize(int8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint8_t), GetSerializeSize(uint8_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int16_t), GetSerializeSize(int16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint16_t), GetSerializeSize(uint16_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int32_t), GetSerializeSize(int32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint32_t), GetSerializeSize(uint32_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(int64_t), GetSerializeSize(int64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(uint64_t), GetSerializeSize(uint64_t(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(float), GetSerializeSize(float(0), 0));
+ BOOST_CHECK_EQUAL(sizeof(double), GetSerializeSize(double(0), 0));
+ // Bool is serialized as char
+ BOOST_CHECK_EQUAL(sizeof(char), GetSerializeSize(bool(0), 0));
+
+ // Sanity-check GetSerializeSize and c++ type matching
+ BOOST_CHECK_EQUAL(GetSerializeSize(char(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint8_t(0), 0), 1);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint16_t(0), 0), 2);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint32_t(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(int64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(uint64_t(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(float(0), 0), 4);
+ BOOST_CHECK_EQUAL(GetSerializeSize(double(0), 0), 8);
+ BOOST_CHECK_EQUAL(GetSerializeSize(bool(0), 0), 1);
+}
+
+BOOST_AUTO_TEST_CASE(floats_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x00000000), 0.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f000000), 0.5F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x3f800000), 1.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40000000), 2.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x40800000), 4.0F);
+ BOOST_CHECK_EQUAL(ser_uint32_to_float(0x44444444), 785.066650390625F);
+
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.0F), 0x00000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(0.5F), 0x3f000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(1.0F), 0x3f800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(2.0F), 0x40000000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(4.0F), 0x40800000);
+ BOOST_CHECK_EQUAL(ser_float_to_uint32(785.066650390625F), 0x44444444);
+}
+
+BOOST_AUTO_TEST_CASE(doubles_conversion)
+{
+ // Choose values that map unambigiously to binary floating point to avoid
+ // rounding issues at the compiler side.
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x0000000000000000ULL), 0.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3fe0000000000000ULL), 0.5);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x3ff0000000000000ULL), 1.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4000000000000000ULL), 2.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4010000000000000ULL), 4.0);
+ BOOST_CHECK_EQUAL(ser_uint64_to_double(0x4088888880000000ULL), 785.066650390625);
+
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.0), 0x0000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(0.5), 0x3fe0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(1.0), 0x3ff0000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(2.0), 0x4000000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(4.0), 0x4010000000000000ULL);
+ BOOST_CHECK_EQUAL(ser_double_to_uint64(785.066650390625), 0x4088888880000000ULL);
+}
+/*
+Python code to generate the below hashes:
+
+ def reversed_hex(x):
+ return binascii.hexlify(''.join(reversed(x)))
+ def dsha256(x):
+ return hashlib.sha256(hashlib.sha256(x).digest()).digest()
+
+ reversed_hex(dsha256(''.join(struct.pack('<f', x) for x in range(0,1000)))) == '8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c'
+ reversed_hex(dsha256(''.join(struct.pack('<d', x) for x in range(0,1000)))) == '43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96'
+*/
+BOOST_AUTO_TEST_CASE(floats)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << float(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("8e8b4cf3e4df8b332057e3e23af42ebc663b61e0495d5e7e32d85099d7f3fe0c"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ float j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
+BOOST_AUTO_TEST_CASE(doubles)
+{
+ CDataStream ss(SER_DISK, 0);
+ // encode
+ for (int i = 0; i < 1000; i++) {
+ ss << double(i);
+ }
+ BOOST_CHECK(Hash(ss.begin(), ss.end()) == uint256S("43d0c82591953c4eafe114590d392676a01585d25b25d433557f0d7878b23f96"));
+
+ // decode
+ for (int i = 0; i < 1000; i++) {
+ double j;
+ ss >> j;
+ BOOST_CHECK_MESSAGE(i == j, "decoded:" << j << " expected:" << i);
+ }
+}
+
BOOST_AUTO_TEST_CASE(varints)
{
// encode
diff --git a/src/txmempool.cpp b/src/txmempool.cpp
index 6e0f7e9c5a..0d50660327 100644
--- a/src/txmempool.cpp
+++ b/src/txmempool.cpp
@@ -337,7 +337,7 @@ public:
void Write(CAutoFile& fileout) const
{
fileout << nBestSeenHeight;
- fileout << history.size();
+ fileout << (uint32_t)history.size();
BOOST_FOREACH(const CBlockAverage& entry, history)
{
entry.Write(fileout);
@@ -348,7 +348,7 @@ public:
{
int nFileBestSeenHeight;
filein >> nFileBestSeenHeight;
- size_t numEntries;
+ uint32_t numEntries;
filein >> numEntries;
if (numEntries <= 0 || numEntries > 10000)
throw runtime_error("Corrupt estimates file. Must have between 1 and 10k entries.");
diff --git a/src/util.cpp b/src/util.cpp
index 0d0f7e5f91..361b3631f5 100644
--- a/src/util.cpp
+++ b/src/util.cpp
@@ -698,13 +698,8 @@ void RenameThread(const char* name)
// removed.
pthread_set_name_np(pthread_self(), name);
-#elif defined(MAC_OSX) && defined(__MAC_OS_X_VERSION_MAX_ALLOWED)
-
-// pthread_setname_np is XCode 10.6-and-later
-#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
+#elif defined(MAC_OSX)
pthread_setname_np(name);
-#endif
-
#else
// Prevent warnings for unused parameters...
(void)name;