diff options
117 files changed, 2396 insertions, 2506 deletions
diff --git a/.gitignore b/.gitignore index c97432df92..7343e722d5 100644 --- a/.gitignore +++ b/.gitignore @@ -45,6 +45,7 @@ src/qt/test/moc*.cpp .deps .dirstamp +.libs .*.swp *.*~* *.bak @@ -66,6 +67,10 @@ src/qt/test/moc*.cpp *.json.h *.raw.h +#libtool object files +*.lo +*.la + # Compilation and Qt preprocessor part *.qm Makefile diff --git a/.travis.yml b/.travis.yml index 567428daf9..1630c1d02a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -59,6 +59,7 @@ script: - cd bitcoin-$HOST - ./configure --cache-file=../config.cache $BITCOIN_CONFIG_ALL $BITCOIN_CONFIG || ( cat config.log && false) - make $MAKEJOBS $GOAL || ( echo "Build failure. Verbose build follows." && make $GOAL V=1 ; false ) + - export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/depends/$HOST/lib - if [ "$RUN_TESTS" = "true" ]; then make check; fi - if [ "$RUN_TESTS" = "true" ]; then qa/pull-tester/rpc-tests.sh; fi after_script: diff --git a/build-aux/m4/ax_gcc_func_attribute.m4 b/build-aux/m4/ax_gcc_func_attribute.m4 new file mode 100644 index 0000000000..275ca63a2c --- /dev/null +++ b/build-aux/m4/ax_gcc_func_attribute.m4 @@ -0,0 +1,217 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE) +# +# DESCRIPTION +# +# This macro checks if the compiler supports one of GCC's function +# attributes; many other compilers also provide function attributes with +# the same syntax. Compiler warnings are used to detect supported +# attributes as unsupported ones are ignored by default so quieting +# warnings when using this macro will yield false positives. +# +# The ATTRIBUTE parameter holds the name of the attribute to be checked. +# +# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>. +# +# The macro caches its result in the ax_cv_have_func_attribute_<attribute> +# variable. +# +# The macro currently supports the following function attributes: +# +# alias +# aligned +# alloc_size +# always_inline +# artificial +# cold +# const +# constructor +# deprecated +# destructor +# dllexport +# dllimport +# error +# externally_visible +# flatten +# format +# format_arg +# gnu_inline +# hot +# ifunc +# leaf +# malloc +# noclone +# noinline +# nonnull +# noreturn +# nothrow +# optimize +# pure +# unused +# used +# visibility +# warning +# warn_unused_result +# weak +# weakref +# +# Unsuppored function attributes will be tested with a prototype returning +# an int and not accepting any arguments and the result of the check might +# be wrong or meaningless so use with care. +# +# LICENSE +# +# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com> +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 2 + +AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [ + AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1]) + + AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([ + m4_case([$1], + [alias], [ + int foo( void ) { return 0; } + int bar( void ) __attribute__(($1("foo"))); + ], + [aligned], [ + int foo( void ) __attribute__(($1(32))); + ], + [alloc_size], [ + void *foo(int a) __attribute__(($1(1))); + ], + [always_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [artificial], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [cold], [ + int foo( void ) __attribute__(($1)); + ], + [const], [ + int foo( void ) __attribute__(($1)); + ], + [constructor], [ + int foo( void ) __attribute__(($1)); + ], + [deprecated], [ + int foo( void ) __attribute__(($1(""))); + ], + [destructor], [ + int foo( void ) __attribute__(($1)); + ], + [dllexport], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [dllimport], [ + int foo( void ) __attribute__(($1)); + ], + [error], [ + int foo( void ) __attribute__(($1(""))); + ], + [externally_visible], [ + int foo( void ) __attribute__(($1)); + ], + [flatten], [ + int foo( void ) __attribute__(($1)); + ], + [format], [ + int foo(const char *p, ...) __attribute__(($1(printf, 1, 2))); + ], + [format_arg], [ + char *foo(const char *p) __attribute__(($1(1))); + ], + [gnu_inline], [ + inline __attribute__(($1)) int foo( void ) { return 0; } + ], + [hot], [ + int foo( void ) __attribute__(($1)); + ], + [ifunc], [ + int my_foo( void ) { return 0; } + static int (*resolve_foo(void))(void) { return my_foo; } + int foo( void ) __attribute__(($1("resolve_foo"))); + ], + [leaf], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [malloc], [ + void *foo( void ) __attribute__(($1)); + ], + [noclone], [ + int foo( void ) __attribute__(($1)); + ], + [noinline], [ + __attribute__(($1)) int foo( void ) { return 0; } + ], + [nonnull], [ + int foo(char *p) __attribute__(($1(1))); + ], + [noreturn], [ + void foo( void ) __attribute__(($1)); + ], + [nothrow], [ + int foo( void ) __attribute__(($1)); + ], + [optimize], [ + __attribute__(($1(3))) int foo( void ) { return 0; } + ], + [pure], [ + int foo( void ) __attribute__(($1)); + ], + [unused], [ + int foo( void ) __attribute__(($1)); + ], + [used], [ + int foo( void ) __attribute__(($1)); + ], + [visibility], [ + int foo_def( void ) __attribute__(($1("default"))); + int foo_hid( void ) __attribute__(($1("hidden"))); + ], + [warning], [ + int foo( void ) __attribute__(($1(""))); + ], + [warn_unused_result], [ + int foo( void ) __attribute__(($1)); + ], + [weak], [ + int foo( void ) __attribute__(($1)); + ], + [weakref], [ + static int foo( void ) { return 0; } + static int bar( void ) __attribute__(($1("foo"))); + ], + [ + m4_warn([syntax], [Unsupported attribute $1, the test may fail]) + int foo( void ) __attribute__(($1)); + ] + )], []) + ], + dnl GCC doesn't exit with an error if an unknown attribute is + dnl provided but only outputs a warning, so accept the attribute + dnl only if no warning were issued. + [AS_IF([test -s conftest.err], + [AS_VAR_SET([ac_var], [no])], + [AS_VAR_SET([ac_var], [yes])])], + [AS_VAR_SET([ac_var], [no])]) + ]) + + AS_IF([test yes = AS_VAR_GET([ac_var])], + [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1, + [Define to 1 if the system has the `$1' function attribute])], []) + + AS_VAR_POPDEF([ac_var]) +]) diff --git a/configure.ac b/configure.ac index c0489f5be7..6784521d81 100644 --- a/configure.ac +++ b/configure.ac @@ -49,7 +49,7 @@ case $host in ;; esac dnl Libtool init checks. -LT_INIT([disable-shared]) +LT_INIT([pic-only]) dnl Check/return PATH for base programs. AC_PATH_TOOL(AR, ar) @@ -201,12 +201,9 @@ case $host in AC_CHECK_LIB([iphlpapi], [main],, AC_MSG_ERROR(lib missing)) AC_CHECK_LIB([crypt32], [main],, AC_MSG_ERROR(lib missing)) - AX_CHECK_LINK_FLAG([[-static-libgcc]],[LDFLAGS="$LDFLAGS -static-libgcc"]) - AX_CHECK_LINK_FLAG([[-static-libstdc++]],[LDFLAGS="$LDFLAGS -static-libstdc++"]) - # -static is interpreted by libtool, where it has a different meaning. # In libtool-speak, it's -all-static. - AX_CHECK_LINK_FLAG([[-static]],[LDFLAGS="$LDFLAGS -static"; LIBTOOL_LDFLAGS="$LIBTOOL_LDFLAGS -all-static"]) + AX_CHECK_LINK_FLAG([[-static]],[LIBTOOL_APP_LDFLAGS="$LIBTOOL_APP_LDFLAGS -all-static"]) AC_PATH_PROG([MAKENSIS], [makensis], none) if test x$MAKENSIS = xnone; then @@ -229,6 +226,15 @@ case $host in *) AC_MSG_ERROR("Could not determine win32/win64 for installer") ;; esac AC_SUBST(WINDOWS_BITS) + + dnl libtool insists upon adding -nostdlib and a list of objects/libs to link against. + dnl That breaks our ability to build dll's with static libgcc/libstdc++/libssp. Override + dnl its command here, with the predeps/postdeps removed, and -static inserted. Postdeps are + dnl also overridden to prevent their insertion later. + dnl This should only affect dll's. + archive_cmds_CXX="\$CC -shared \$libobjs \$deplibs \$compiler_flags -static -o \$output_objdir/\$soname \${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker \$lib" + postdeps_CXX= + ;; *darwin*) TARGET_OS=darwin @@ -279,6 +285,7 @@ case $host in esac fi + AX_CHECK_LINK_FLAG([[-Wl,-headerpad_max_install_names]], [LDFLAGS="$LDFLAGS -Wl,-headerpad_max_install_names"]) CPPFLAGS="$CPPFLAGS -DMAC_OSX" ;; *linux*) @@ -349,6 +356,10 @@ fi AX_CHECK_LINK_FLAG([[-Wl,--large-address-aware]], [LDFLAGS="$LDFLAGS -Wl,--large-address-aware"]) +AX_GCC_FUNC_ATTRIBUTE([visibility]) +AX_GCC_FUNC_ATTRIBUTE([dllexport]) +AX_GCC_FUNC_ATTRIBUTE([dllimport]) + if test x$use_glibc_compat != xno; then #__fdelt_chk's params and return type have changed from long unsigned int to long int. @@ -389,6 +400,12 @@ if test x$use_hardening != xno; then AX_CHECK_LINK_FLAG([[-pie]], [HARDENED_LDFLAGS="$HARDENED_LDFLAGS -pie"]) fi + case $host in + *mingw*) + AC_CHECK_LIB([ssp], [main],, AC_MSG_ERROR(lib missing)) + ;; + esac + CXXFLAGS="$CXXFLAGS $HARDENED_CXXFLAGS" CPPFLAGS="$CPPFLAGS $HARDENED_CPPFLAGS" LDFLAGS="$LDFLAGS $HARDENED_LDFLAGS" @@ -603,6 +620,12 @@ AC_ARG_WITH([utils], [build_bitcoin_utils=$withval], [build_bitcoin_utils=yes]) +AC_ARG_WITH([libs], + [AS_HELP_STRING([--with-libs], + [build libraries (default=yes)])], + [build_bitcoin_libs=$withval], + [build_bitcoin_libs=yes]) + AC_ARG_WITH([daemon], [AS_HELP_STRING([--with-daemon], [build bitcoind daemon (default=yes)])], @@ -653,6 +676,13 @@ AC_MSG_CHECKING([whether to build utils (bitcoin-cli bitcoin-tx)]) AM_CONDITIONAL([BUILD_BITCOIN_UTILS], [test x$build_bitcoin_utils = xyes]) AC_MSG_RESULT($build_bitcoin_utils) +AC_MSG_CHECKING([whether to build libraries]) +AM_CONDITIONAL([BUILD_BITCOIN_LIBS], [test x$build_bitcoin_libs = xyes]) +if test x$build_bitcoin_libs = xyes; then + AC_DEFINE(HAVE_CONSENSUS_LIB, 1, [Define this symbol if the consensus lib has been built]) +fi +AC_MSG_RESULT($build_bitcoin_libs) + dnl sets $bitcoin_enable_qt, $bitcoin_enable_qt_test, $bitcoin_enable_qt_dbus BITCOIN_QT_CONFIGURE([$use_pkgconfig], [qt4]) @@ -769,8 +799,8 @@ else AC_MSG_RESULT([no]) fi -if test x$build_bitcoin_utils$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then - AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-daemon --with-gui or --enable-tests]) +if test x$build_bitcoin_utils$build_bitcoin_libs$build_bitcoind$bitcoin_enable_qt$use_tests = xnononono; then + AC_MSG_ERROR([No targets! Please specify at least one of: --with-utils --with-libs --with-daemon --with-gui or --enable-tests]) fi AM_CONDITIONAL([TARGET_DARWIN], [test x$TARGET_OS = xdarwin]) @@ -801,7 +831,7 @@ AC_SUBST(CLIENT_VERSION_IS_RELEASE, _CLIENT_VERSION_IS_RELEASE) AC_SUBST(COPYRIGHT_YEAR, _COPYRIGHT_YEAR) AC_SUBST(RELDFLAGS) -AC_SUBST(LIBTOOL_LDFLAGS) +AC_SUBST(LIBTOOL_APP_LDFLAGS) AC_SUBST(USE_UPNP) AC_SUBST(USE_QRCODE) AC_SUBST(BOOST_LIBS) diff --git a/contrib/gitian-descriptors/README.md b/contrib/gitian-descriptors/README.md index 7a67263ee4..061b897d2a 100644 --- a/contrib/gitian-descriptors/README.md +++ b/contrib/gitian-descriptors/README.md @@ -27,7 +27,6 @@ Once you've got the right hardware and software: # Create base images cd gitian-builder - bin/make-base-vm --suite precise --arch i386 bin/make-base-vm --suite precise --arch amd64 cd .. diff --git a/contrib/gitian-descriptors/boost-linux.yml b/contrib/gitian-descriptors/boost-linux.yml deleted file mode 100644 index bd35346337..0000000000 --- a/contrib/gitian-descriptors/boost-linux.yml +++ /dev/null @@ -1,55 +0,0 @@ ---- -name: "boost" -suites: -- "precise" -architectures: -- "i386" -- "amd64" -packages: -- "g++" -- "unzip" -- "pkg-config" -- "libtool" -- "faketime" -- "bsdmainutils" -- "zip" -- "libz-dev" -reference_datetime: "2011-01-30 00:00:00" -remotes: [] -files: -- "boost_1_55_0.tar.bz2" -script: | - STAGING="$HOME/install" - TEMPDIR="$HOME/tmp" - export LIBRARY_PATH="$STAGING/lib" - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - export TZ=UTC - # Input Integrity Check - echo "fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52 boost_1_55_0.tar.bz2" | shasum -c - - mkdir -p "$STAGING" - tar --warning=no-timestamp -xjf boost_1_55_0.tar.bz2 - cd boost_1_55_0 - GCCVERSION=$(g++ -E -dM $(mktemp --suffix=.h) | grep __VERSION__ | cut -d ' ' -f 3 | cut -d '"' -f 2) - # note: bjam with -d+2 reveals that -O3 is implied by default, no need to provide it in cxxflags - echo "using gcc : $GCCVERSION : g++ - : - <cxxflags>\"-frandom-seed=boost1 -fPIC\" - ;" > user-config.jam - - ./bootstrap.sh --without-icu - - ./bjam toolset=gcc threadapi=pthread threading=multi variant=release link=static runtime-link=shared --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 --layout=tagged --build-type=complete --prefix="$STAGING" $MAKEOPTS -d+2 install - - # post-process all generated libraries to be deterministic - # extract them to a temporary directory then re-build them deterministically - for LIB in $(find $STAGING -name \*.a); do - rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR - ar xv $LIB | cut -b5- > /tmp/list.txt - rm $LIB - ar crsD $LIB $(cat /tmp/list.txt) - done - # - cd "$STAGING" - find | sort | zip -X@ $OUTDIR/boost-linux${GBUILD_BITS}-1.55.0-gitian-r1.zip diff --git a/contrib/gitian-descriptors/boost-win.yml b/contrib/gitian-descriptors/boost-win.yml deleted file mode 100644 index 347952e3a6..0000000000 --- a/contrib/gitian-descriptors/boost-win.yml +++ /dev/null @@ -1,86 +0,0 @@ ---- -name: "boost" -suites: -- "precise" -architectures: -- "amd64" -packages: -- "mingw-w64" -- "g++-mingw-w64" -- "faketime" -- "zip" -reference_datetime: "2011-01-30 00:00:00" -remotes: [] -files: -- "boost_1_55_0.tar.bz2" -- "boost-mingw-gas-cross-compile-2013-03-03.patch" -script: | - # Defines - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - export TZ=UTC - INDIR=$HOME/build - TEMPDIR=$HOME/tmp - # Input Integrity Check - echo "fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52 boost_1_55_0.tar.bz2" | shasum -c - echo "d2b7f6a1d7051faef3c9cf41a92fa3671d905ef1e1da920d07651a43299f6268 boost-mingw-gas-cross-compile-2013-03-03.patch" | shasum -c - - for BITS in 32 64; do # for architectures - # - INSTALLPREFIX=$HOME/staging${BITS} - BUILDDIR=$HOME/build${BITS} - if [ "x$BITS" = "x32" ]; then - HOST=i686-w64-mingw32 - else - HOST=x86_64-w64-mingw32 - fi - # - mkdir -p $INSTALLPREFIX $BUILDDIR - cd $BUILDDIR - # - tar --warning=no-timestamp -xjf $INDIR/boost_1_55_0.tar.bz2 - cd boost_1_55_0 - GCCVERSION=$($HOST-g++ -E -dM $(mktemp --suffix=.h) | grep __VERSION__ | cut -d ' ' -f 3 | cut -d '"' -f 2) - echo "using gcc : $GCCVERSION : $HOST-g++ - : - <rc>$HOST-windres - <archiver>$HOST-ar - <cxxflags>-frandom-seed=boost1 - <ranlib>$HOST-ranlib - ;" > user-config.jam - ./bootstrap.sh --without-icu - - # Workaround: Upstream boost dev refuses to include patch that would allow Free Software cross-compile toolchain to work - # This patch was authored by the Fedora package developer and ships in Fedora's mingw32-boost. - # Please obtain the exact patch that matches the above sha256sum from one of the following mirrors. - # - # Read History: https://svn.boost.org/trac/boost/ticket/7262 - # History Mirror: http://rose.makesad.us/~paulproteus/mirrors/7262%20Boost.Context%20fails%20to%20build%20using%20MinGW.html - # - # Patch: https://svn.boost.org/trac/boost/raw-attachment/ticket/7262/boost-mingw.patch - # Patch Mirror: http://wtogami.fedorapeople.org/boost-mingw-gas-cross-compile-2013-03-03.patch - # Patch Mirror: http://mindstalk.net/host/boost-mingw-gas-cross-compile-2013-03-03.patch - # Patch Mirror: http://rose.makesad.us/~paulproteus/mirrors/boost-mingw-gas-cross-compile-2013-03-03.patch - patch -p0 < $INDIR/boost-mingw-gas-cross-compile-2013-03-03.patch - - # Bug Workaround: boost-1.54.0 broke the ability to disable zlib, still broken in 1.55 - # https://svn.boost.org/trac/boost/ticket/9156 - sed -i 's^\[ ac.check-library /zlib//zlib : <library>/zlib//zlib^^' libs/iostreams/build/Jamfile.v2 - sed -i 's^<source>zlib.cpp <source>gzip.cpp \]^^' libs/iostreams/build/Jamfile.v2 - - # http://statmt.org/~s0565741/software/boost_1_52_0/libs/context/doc/html/context/requirements.html - # "For cross-compiling the lib you must specify certain additional properties at bjam command line: target-os, abi, binary-format, architecture and address-model." - ./bjam toolset=gcc binary-format=pe target-os=windows threadapi=win32 address-model=$BITS threading=multi variant=release link=static runtime-link=static --user-config=user-config.jam --without-mpi --without-python -sNO_BZIP2=1 -sNO_ZLIB=1 --layout=tagged --build-type=complete --prefix="$INSTALLPREFIX" $MAKEOPTS install - # post-process all generated libraries to be deterministic - # extract them to a temporary directory then re-build them deterministically - for LIB in $(find $INSTALLPREFIX -name \*.a); do - rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR - $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt - rm $LIB - $HOST-ar crsD $LIB $(cat /tmp/list.txt) - done - # - cd "$INSTALLPREFIX" - find | sort | zip -X@ $OUTDIR/boost-win$BITS-1.55.0-gitian-r6.zip - done # for BITS in - diff --git a/contrib/gitian-descriptors/deps-linux.yml b/contrib/gitian-descriptors/deps-linux.yml deleted file mode 100644 index 8221222133..0000000000 --- a/contrib/gitian-descriptors/deps-linux.yml +++ /dev/null @@ -1,98 +0,0 @@ ---- -name: "bitcoin" -suites: -- "precise" -architectures: -- "i386" -- "amd64" -packages: -- "g++" -- "unzip" -- "zip" -- "pkg-config" -- "libtool" -- "faketime" -- "bsdmainutils" -reference_datetime: "2013-06-01 00:00:00" -remotes: [] -files: -- "openssl-1.0.1h.tar.gz" -- "miniupnpc-1.9.tar.gz" -- "qrencode-3.4.3.tar.bz2" -- "protobuf-2.5.0.tar.bz2" -- "db-4.8.30.NC.tar.gz" -script: | - STAGING="$HOME/install" - TEMPDIR="$HOME/tmp" - OPTFLAGS='-O2' - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - export TZ=UTC - export LIBRARY_PATH="$STAGING/lib" - # Integrity Check - echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c - echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c - echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c - echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c - echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c - - # - tar xzf openssl-1.0.1h.tar.gz - cd openssl-1.0.1h - # need -fPIC to avoid relocation error in 64 bit builds - ./config no-shared no-zlib no-dso no-krb5 --openssldir=$STAGING -fPIC - # need to build OpenSSL with faketime because a timestamp is embedded into cversion.o - make - make install_sw - cd .. - # - tar xzfm miniupnpc-1.9.tar.gz - cd miniupnpc-1.9 - # miniupnpc is always built with -fPIC - INSTALLPREFIX=$STAGING make $MAKEOPTS install - rm -f $STAGING/lib/libminiupnpc.so* # no way to skip shared lib build - cd .. - # - tar xjf qrencode-3.4.3.tar.bz2 - cd qrencode-3.4.3 - unset FAKETIME # unset fake time during configure, as it does some clock sanity tests - # need --with-pic to avoid relocation error in 64 bit builds - ./configure --prefix=$STAGING --enable-static --disable-shared --with-pic --without-tools --disable-dependency-tracking - # Workaround to prevent re-configuring by make; make all files have a date in the past - find . -print0 | xargs -r0 touch -t 200001010000 - export FAKETIME=$REFERENCE_DATETIME - make $MAKEOPTS install - cd .. - # - tar xjf protobuf-2.5.0.tar.bz2 - cd protobuf-2.5.0 - mkdir -p $STAGING/host/bin - unset FAKETIME # unset fake time during configure, as it does some clock sanity tests - # need --with-pic to avoid relocation error in 64 bit builds - ./configure --prefix=$STAGING --bindir=$STAGING/host/bin --enable-static --disable-shared --with-pic --without-zlib - # Workaround to prevent re-configuring by make; make all files have a date in the past - find . -print0 | xargs -r0 touch -t 200001010000 - export FAKETIME=$REFERENCE_DATETIME - make $MAKEOPTS install - cd .. - # - tar xzf db-4.8.30.NC.tar.gz - cd db-4.8.30.NC/build_unix - # need --with-pic to avoid relocation error in 64 bit builds - ../dist/configure --prefix=$STAGING --enable-cxx --disable-shared --with-pic - # Workaround to prevent re-configuring by make; make all files have a date in the past - find . -print0 | xargs -r0 touch -t 200001010000 - make $MAKEOPTS library_build - make install_lib install_include - cd ../.. - # post-process all generated libraries to be deterministic - # extract them to a temporary directory then re-build them deterministically - for LIB in $(find $STAGING -name \*.a); do - rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR - ar xv $LIB | cut -b5- > /tmp/list.txt - rm $LIB - ar crsD $LIB $(cat /tmp/list.txt) - done - # - cd $STAGING - find include lib bin host | sort | zip -X@ $OUTDIR/bitcoin-deps-linux${GBUILD_BITS}-gitian-r6.zip diff --git a/contrib/gitian-descriptors/deps-win.yml b/contrib/gitian-descriptors/deps-win.yml deleted file mode 100644 index fe02950ef9..0000000000 --- a/contrib/gitian-descriptors/deps-win.yml +++ /dev/null @@ -1,128 +0,0 @@ ---- -name: "bitcoin-deps" -suites: -- "precise" -architectures: -- "amd64" -packages: -- "mingw-w64" -- "g++-mingw-w64" -- "git-core" -- "zip" -- "faketime" -- "psmisc" -reference_datetime: "2011-01-30 00:00:00" -remotes: [] -files: -- "openssl-1.0.1h.tar.gz" -- "db-4.8.30.NC.tar.gz" -- "miniupnpc-1.9.tar.gz" -- "zlib-1.2.8.tar.gz" -- "libpng-1.6.8.tar.gz" -- "qrencode-3.4.3.tar.bz2" -script: | - # - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - export TZ=UTC - INDIR=$HOME/build - TEMPDIR=$HOME/tmp - # Input Integrity Check - echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c - echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c - echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c - echo "36658cb768a54c1d4dec43c3116c27ed893e88b02ecfcb44f2166f9c0b7f2a0d zlib-1.2.8.tar.gz" | sha256sum -c - echo "32c7acf1608b9c8b71b743b9780adb7a7b347563dbfb4a5263761056da44cc96 libpng-1.6.8.tar.gz" | sha256sum -c - echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c - - for BITS in 32 64; do # for architectures - # - INSTALLPREFIX=$HOME/staging${BITS} - BUILDDIR=$HOME/build${BITS} - if [ "x$BITS" = "x32" ]; then - HOST=i686-w64-mingw32 - else - HOST=x86_64-w64-mingw32 - fi - # - mkdir -p $INSTALLPREFIX $BUILDDIR - cd $BUILDDIR - # - tar xzf $INDIR/openssl-1.0.1h.tar.gz - cd openssl-1.0.1h - if [ "x$BITS" = "x32" ]; then - OPENSSL_TGT=mingw - else - OPENSSL_TGT=mingw64 - fi - ./Configure --cross-compile-prefix=$HOST- ${OPENSSL_TGT} no-shared no-dso --openssldir=$INSTALLPREFIX - make - make install_sw - cd .. - # - tar xzf $INDIR/db-4.8.30.NC.tar.gz - cd db-4.8.30.NC/build_unix - ../dist/configure --prefix=$INSTALLPREFIX --enable-mingw --enable-cxx --host=$HOST --disable-shared - make $MAKEOPTS library_build - make install_lib install_include - cd ../.. - # - tar xzf $INDIR/miniupnpc-1.9.tar.gz - cd miniupnpc-1.9 - echo " - --- miniupnpc-1.9/Makefile.mingw.orig 2013-09-29 18:52:51.014087958 -1000 - +++ miniupnpc-1.9/Makefile.mingw 2013-09-29 19:09:29.663318691 -1000 - @@ -67,8 +67,8 @@ - - wingenminiupnpcstrings.o: wingenminiupnpcstrings.c - - -miniupnpcstrings.h: miniupnpcstrings.h.in wingenminiupnpcstrings - - wingenminiupnpcstrings \$< \$@ - +miniupnpcstrings.h: miniupnpcstrings.h.in - + sed -e 's|OS/version|MSWindows/5.1.2600|' -e 's|MINIUPNPC_VERSION_STRING \"version\"|MINIUPNPC_VERSION_STRING \"VERSIONHERE\"|' \$< > \$@ - - minixml.o: minixml.c minixml.h miniupnpcstrings.h - - " | sed "s/VERSIONHERE/$(cat VERSION)/" | patch -p1 - mkdir -p dll - make -f Makefile.mingw CC=$HOST-gcc AR=$HOST-ar libminiupnpc.a - install -d $INSTALLPREFIX/include/miniupnpc - install *.h $INSTALLPREFIX/include/miniupnpc - install libminiupnpc.a $INSTALLPREFIX/lib - cd .. - # - tar xzf $INDIR/zlib-1.2.8.tar.gz - cd zlib-1.2.8 - CROSS_PREFIX=$HOST- ./configure --prefix=$INSTALLPREFIX --static - make - make install - cd .. - # - tar xzf $INDIR/libpng-1.6.8.tar.gz - cd libpng-1.6.8 - OPT="-O2" - CPPFLAGS="${OPT} -I$INSTALLPREFIX/include" CFLAGS="${OPT} -I$INSTALLPREFIX/include" LDFLAGS="${OPT} -L$INSTALLPREFIX/lib" ./configure --disable-shared --prefix=$INSTALLPREFIX --host=$HOST - make $MAKEOPTS - make install - cd .. - # - tar xjf $INDIR/qrencode-3.4.3.tar.bz2 - cd qrencode-3.4.3 - png_CFLAGS="-I$INSTALLPREFIX/include" png_LIBS="-L$INSTALLPREFIX/lib -lpng" ./configure --prefix=$INSTALLPREFIX --host=$HOST --enable-static --disable-shared --without-tools --disable-dependency-tracking - # Workaround to prevent re-configuring by make (resulting in missing m4 error); make all files have a date in the past - find . -print0 | xargs -r0 touch -t 200001010000 - make - make install - cd .. - # post-process all generated libraries to be deterministic - # extract them to a temporary directory then re-build them deterministically - for LIB in $(find $INSTALLPREFIX -name \*.a); do - rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR - $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt - rm $LIB - $HOST-ar crsD $LIB $(cat /tmp/list.txt) - done - # - cd $INSTALLPREFIX - find include lib | sort | zip -X@ $OUTDIR/bitcoin-deps-win$BITS-gitian-r13.zip - done # for BITS in diff --git a/contrib/gitian-descriptors/gitian-linux.yml b/contrib/gitian-descriptors/gitian-linux.yml index 30b0227bdd..b57a04469c 100644 --- a/contrib/gitian-descriptors/gitian-linux.yml +++ b/contrib/gitian-descriptors/gitian-linux.yml @@ -1,86 +1,104 @@ --- -name: "bitcoin" +name: "bitcoin-linux-0.10" +enable_cache: true suites: - "precise" architectures: -- "i386" - "amd64" packages: -- "g++" +- "g++-multilib" - "git-core" -- "unzip" - "pkg-config" - "autoconf2.13" - "libtool" - "automake" - "faketime" - "bsdmainutils" -- "libqt4-core" -- "libqt4-gui" -- "libqt4-dbus" -- "libqt4-network" -- "libqt4-test" +- "binutils-gold" reference_datetime: "2013-06-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" -files: -- "bitcoin-deps-linux32-gitian-r6.zip" -- "bitcoin-deps-linux64-gitian-r6.zip" -- "boost-linux32-1.55.0-gitian-r1.zip" -- "boost-linux64-1.55.0-gitian-r1.zip" -- "qt-linux32-4.6.4-gitian-r1.tar.gz" -- "qt-linux64-4.6.4-gitian-r1.tar.gz" +files: [] script: | - STAGING="$HOME/install" - OPTFLAGS='-O2' - BINDIR="${OUTDIR}/bin/${GBUILD_BITS}" # 32/64 bit build specific output directory - TEMPDIR="$HOME/tempdir" - export TZ=UTC - export LIBRARY_PATH="$STAGING/lib" - export PATH="$STAGING/bin:$PATH" - mkdir -p ${BINDIR} - # - mkdir -p $STAGING - cd $STAGING - unzip ../build/bitcoin-deps-linux${GBUILD_BITS}-gitian-r6.zip - unzip ../build/boost-linux${GBUILD_BITS}-1.55.0-gitian-r1.zip - tar -zxf ../build/qt-linux${GBUILD_BITS}-4.6.4-gitian-r1.tar.gz - cd ../build + WRAP_DIR=$HOME/wrapped + HOSTS="i686-pc-linux-gnu x86_64-unknown-linux-gnu" + CONFIGFLAGS="--enable-upnp-default --enable-glibc-back-compat" + FAKETIME_HOST_PROGS="" + FAKETIME_PROGS="date ar ranlib nm strip" + + export QT_RCC_TEST=1 + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + # Create global faketime wrappers + for prog in ${FAKETIME_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + + # Create per-host faketime wrappers + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + export PATH=${WRAP_DIR}:${PATH} - # Avoid exporting *any* symbols from the executable - # This avoids conflicts between the libraries statically linked into bitcoin and any - # libraries we may link dynamically (such as Qt and OpenSSL, see issue #4094). - # It also avoids start-up overhead to not export any unnecessary symbols. - # To do this, build a linker script that marks all symbols as local. - LINKER_SCRIPT=$HOME/build/linker_version_script - echo ' - { - local: *; - };' > $LINKER_SCRIPT - function do_configure { - ./configure "$@" --enable-upnp-default --prefix=$STAGING --with-protoc-bindir=$STAGING/host/bin --with-qt-bindir=$STAGING/bin --with-boost=$STAGING --disable-maintainer-mode --disable-dependency-tracking PKG_CONFIG_PATH="$STAGING/lib/pkgconfig" CPPFLAGS="-I$STAGING/include ${OPTFLAGS}" LDFLAGS="-L$STAGING/lib -Wl,--version-script=$LINKER_SCRIPT ${OPTFLAGS}" CXXFLAGS="-frandom-seed=bitcoin ${OPTFLAGS}" --enable-glibc-back-compat - } - # cd bitcoin + BASEPREFIX=`pwd`/depends + # Build dependencies for each host + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + done + + # Create the release tarball using (arbitrarily) the first host ./autogen.sh - do_configure + ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` make dist DISTNAME=`echo bitcoin-*.tar.gz` - # Build dynamic versions of everything - # (with static linking to boost and openssl as well a some non-OS deps) - mkdir -p distsrc - cd distsrc - tar --strip-components=1 -xf ../$DISTNAME - do_configure --bindir=$BINDIR - make $MAKEOPTS - make $MAKEOPTS install-strip - make $MAKEOPTS clean + # Correct tar file order + mkdir -p temp + pushd temp + tar xf ../$DISTNAME + find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$DISTNAME + popd + + ORIGPATH="$PATH" + # Extract the release tarball into a dir for each host and build + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir -p distsrc-${i} + cd distsrc-${i} + tar --strip-components=1 -xf ../$DISTNAME - # sort distribution tar file and normalize user/group/mtime information for deterministic output + ./configure --prefix=${BASEPREFIX}/${i} --bindir=${OUTDIR}/${i}/bin --includedir=${OUTDIR}/${i}/include --libdir=${OUTDIR}/${i}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + make ${MAKEOPTS} + make install-strip + cd .. + done mkdir -p $OUTDIR/src - rm -rf $TEMPDIR - mkdir -p $TEMPDIR - cd $TEMPDIR - tar -xvf $HOME/build/bitcoin/$DISTNAME | sort | tar --no-recursion -cT /dev/stdin --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 --mtime="$REFERENCE_DATETIME" | gzip -n > $OUTDIR/src/$DISTNAME + mv $DISTNAME $OUTDIR/src + mv ${OUTDIR}/x86_64-* ${OUTDIR}/64 + mv ${OUTDIR}/i686-* ${OUTDIR}/32 + + # Delete unwanted stuff + find ${OUTDIR} -name "lib*.la" -delete diff --git a/contrib/gitian-descriptors/gitian-osx-bitcoin.yml b/contrib/gitian-descriptors/gitian-osx-bitcoin.yml deleted file mode 100644 index bc3d561c35..0000000000 --- a/contrib/gitian-descriptors/gitian-osx-bitcoin.yml +++ /dev/null @@ -1,61 +0,0 @@ ---- -name: "bitcoin" -suites: -- "precise" -architectures: -- "i386" -packages: -- "git-core" -- "automake" -- "faketime" -- "bsdmainutils" -- "pkg-config" -- "p7zip-full" -- "libtool" - -reference_datetime: "2013-06-01 00:00:00" -remotes: -- "url": "https://github.com/bitcoin/bitcoin.git" - "dir": "bitcoin" -files: -- "osx-native-depends-r3.tar.gz" -- "osx-depends-r4.tar.gz" -- "osx-depends-qt-5.2.1-r4.tar.gz" -- "MacOSX10.7.sdk.tar.gz" - -script: | - - HOST=x86_64-apple-darwin11 - PREFIX=`pwd`/osx-cross-depends/prefix - SDK=`pwd`/osx-cross-depends/SDKs/MacOSX10.7.sdk - NATIVEPREFIX=`pwd`/osx-cross-depends/native-prefix - export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" - - export SOURCES_PATH=`pwd` - - mkdir -p osx-cross-depends/SDKs - - tar -C osx-cross-depends/SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz - - tar -C osx-cross-depends -xf osx-native-depends-r3.tar.gz - tar -C osx-cross-depends -xf osx-depends-r4.tar.gz - tar -C osx-cross-depends -xf osx-depends-qt-5.2.1-r4.tar.gz - export PATH=`pwd`/osx-cross-depends/native-prefix/bin:$PATH - - cd bitcoin - - export ZERO_AR_DATE=1 - export QT_RCC_TEST=1 - ./autogen.sh - ./configure --host=${HOST} --with-boost=${PREFIX} CC=clang CXX=clang++ OBJC=clang OBJCXX=clang++ CFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" CXXFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" LDFLAGS="-B${NATIVEPREFIX}/bin -L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" CPPFLAGS="-I${NATIVEPREFIX}/lib/clang/3.2/include -I${PREFIX}/include" SSL_LIBS="-lz -lssl -lcrypto" --disable-tests -with-gui=qt5 PKG_CONFIG_LIBDIR="${PREFIX}/lib/pkgconfig" --disable-dependency-tracking --disable-maintainer-mode - make dist - mkdir -p distsrc - cd distsrc - tar --strip-components=1 -xf ../bitcoin-*.tar* - ./configure --host=${HOST} --with-boost=${PREFIX} CC=clang CXX=clang++ OBJC=clang OBJCXX=clang++ CFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" CXXFLAGS="-target ${HOST} -mmacosx-version-min=10.6 --sysroot ${SDK} -msse2 -Qunused-arguments" LDFLAGS="-B${NATIVEPREFIX}/bin -L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" CPPFLAGS="-I${NATIVEPREFIX}/lib/clang/3.2/include -I${PREFIX}/include" SSL_LIBS="-lz -lssl -lcrypto" --disable-tests -with-gui=qt5 PKG_CONFIG_LIBDIR="${PREFIX}/lib/pkgconfig" --disable-dependency-tracking --disable-maintainer-mode - make $MAKEOPTS - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - export TZ=UTC - make deploy - dmg dmg Bitcoin-Qt.dmg $OUTDIR/Bitcoin-Qt.dmg diff --git a/contrib/gitian-descriptors/gitian-osx-depends.yml b/contrib/gitian-descriptors/gitian-osx-depends.yml deleted file mode 100644 index 07a021cf0c..0000000000 --- a/contrib/gitian-descriptors/gitian-osx-depends.yml +++ /dev/null @@ -1,159 +0,0 @@ ---- -name: "osx-depends" -suites: -- "precise" -architectures: -- "i386" -packages: -- "git-core" -- "automake" -- "p7zip-full" - -reference_datetime: "2013-06-01 00:00:00" -remotes: [] -files: -- "boost_1_55_0.tar.bz2" -- "db-4.8.30.NC.tar.gz" -- "miniupnpc-1.9.tar.gz" -- "openssl-1.0.1h.tar.gz" -- "protobuf-2.5.0.tar.bz2" -- "qrencode-3.4.3.tar.bz2" -- "MacOSX10.7.sdk.tar.gz" -- "osx-native-depends-r3.tar.gz" - -script: | - - echo "fff00023dd79486d444c8e29922f4072e1d451fc5a4d2b6075852ead7f2b7b52 boost_1_55_0.tar.bz2" | sha256sum -c - echo "12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef db-4.8.30.NC.tar.gz" | sha256sum -c - echo "2923e453e880bb949e3d4da9f83dd3cb6f08946d35de0b864d0339cf70934464 miniupnpc-1.9.tar.gz" | sha256sum -c - echo "9d1c8a9836aa63e2c6adb684186cbd4371c9e9dcc01d6e3bb447abf2d4d3d093 openssl-1.0.1h.tar.gz" | sha256sum -c - echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c - echo "dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b50597a98 qrencode-3.4.3.tar.bz2" | sha256sum -c - - REVISION=r4 - export SOURCES_PATH=`pwd` - export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" - export PATH=$HOME:$PATH - export SOURCES_PATH=`pwd` - export ZERO_AR_DATE=1 - - mkdir -p osx-cross-depends/build - cd osx-cross-depends - - PREFIX=`pwd`/prefix - NATIVEPREFIX=`pwd`/native-prefix - BUILD_BASE=`pwd`/build - SDK=`pwd`/SDKs/MacOSX10.7.sdk - HOST=x86_64-apple-darwin11 - MIN_VERSION=10.6 - - INT_CFLAGS="-target ${HOST} -mmacosx-version-min=${MIN_VERSION} --sysroot ${SDK} -msse2 -Qunused-arguments" - INT_CXXFLAGS="${INT_CFLAGS}" - INT_LDFLAGS="-L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" - INT_LDFLAGS_CLANG="-B${NATIVEPREFIX}/bin" - INT_CPPFLAGS="-I${PREFIX}/include" - INT_CC=clang - INT_CXX=clang++ - INT_OBJC=clang - INT_OBJCXX=clang++ - INT_AR=${HOST}-ar - INT_RANLIB=${HOST}-ranlib - INT_LIBTOOL=${HOST}-libtool - INT_INSTALL_NAME_TOOL=${HOST}-install_name_tool - - export PATH=${NATIVEPREFIX}/bin:${PATH} - - mkdir -p ${NATIVEPREFIX}/bin - mkdir -p ${NATIVEPREFIX}/lib - mkdir -p ${PREFIX}/bin - mkdir -p ${PREFIX}/lib - mkdir -p ${BUILD_BASE} - - mkdir -p SDKs - tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz - - tar xf /home/ubuntu/build/osx-native-depends-r3.tar.gz - - # bdb - SOURCE_FILE=${SOURCES_PATH}/db-4.8.30.NC.tar.gz - BUILD_DIR=${BUILD_BASE}/db-4.8.30.NC - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - sed -i 's/__atomic_compare_exchange/__atomic_compare_exchange_db/g' ${BUILD_DIR}/dbinc/atomic.h - pushd ${BUILD_DIR} - cd build_unix; - ../dist/configure --host=${HOST} --prefix="${PREFIX}" --disable-shared --enable-cxx CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}" - make $MAKEOPTS libdb.a libdb_cxx.a - make install_lib install_include - popd - - # openssl - SOURCE_FILE=${SOURCES_PATH}/openssl-1.0.1h.tar.gz - BUILD_DIR=${BUILD_BASE}/openssl-1.0.1h - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - pushd ${BUILD_DIR} - sed -ie "s|cc:|${INT_CC}:|" ${BUILD_DIR}/Configure - sed -ie "s|\(-arch [_a-zA-Z0-9]*\)|\1 --sysroot ${SDK} -target ${HOST} -msse2|" ${BUILD_DIR}/Configure - AR="${INT_AR}" RANLIB="${INT_RANLIB}" ./Configure --prefix=${PREFIX} --openssldir=${PREFIX}/etc/openssl zlib shared no-krb5 darwin64-x86_64-cc ${INT_LDFLAGS} ${INT_CLANG_LDFLAGS} ${INT_CPPFLAGS} - sed -i "s|engines apps test|engines|" ${BUILD_DIR}/Makefile - sed -i "/define DATE/d" ${BUILD_DIR}/crypto/Makefile - make -j1 build_libs libcrypto.pc libssl.pc openssl.pc - make -j1 install_sw - popd - - #libminiupnpc - SOURCE_FILE=${SOURCES_PATH}/miniupnpc-1.9.tar.gz - BUILD_DIR=${BUILD_BASE}/miniupnpc-1.9 - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - pushd ${BUILD_DIR} - CFLAGS="${INT_CFLAGS} ${INT_CPPFLAGS}" make $MAKEOPTS OS=Darwin CC="${INT_CC}" AR="${INT_AR}" libminiupnpc.a - install -d ${PREFIX}/include/miniupnpc - install *.h ${PREFIX}/include/miniupnpc - install libminiupnpc.a ${PREFIX}/lib - popd - - # qrencode - SOURCE_FILE=${SOURCES_PATH}/qrencode-3.4.3.tar.bz2 - BUILD_DIR=${BUILD_BASE}/qrencode-3.4.3 - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - pushd ${BUILD_DIR} - - # m4 folder is not included in the stable release, which can confuse aclocal - # if its timestamp ends up being earlier than configure.ac when extracted - touch aclocal.m4 - ./configure --host=${HOST} --prefix="${PREFIX}" --disable-shared CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}" --disable-shared -without-tools --disable-sdltest --disable-dependency-tracking - make $MAKEOPTS - make install - popd - - # libprotobuf - SOURCE_FILE=${SOURCES_PATH}/protobuf-2.5.0.tar.bz2 - BUILD_DIR=${BUILD_BASE}/protobuf-2.5.0 - - tar -C ${BUILD_BASE} -xjf ${SOURCE_FILE} - pushd ${BUILD_DIR} - ./configure --host=${HOST} --prefix="${PREFIX}" --disable-shared --enable-cxx CC="${INT_CC}" CXX="${INT_CXX}" AR="${INT_AR}" RANLIB="${INT_RANLIB}" OBJC="${INT_OBJC}" OBJCXX="${INT_OBJCXX}" CFLAGS="${INT_CFLAGS}" CXXFLAGS="${INT_CXXFLAGS}" LDFLAGS="${INT_CLANG_LDFLAGS} ${INT_LDFLAGS}" CPPFLAGS="${INT_CPPFLAGS}" --enable-shared=no --disable-dependency-tracking --with-protoc=${NATIVEPREFIX}/bin/protoc - cd src - make $MAKEOPTS libprotobuf.la - make install-libLTLIBRARIES install-nobase_includeHEADERS - cd .. - make install-pkgconfigDATA - popd - - # boost - SOURCE_FILE=${SOURCES_PATH}/boost_1_55_0.tar.bz2 - BUILD_DIR=${BUILD_BASE}/boost_1_55_0 - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - pushd ${BUILD_DIR} - ./bootstrap.sh --with-libraries=chrono,filesystem,program_options,system,thread,test - echo "using darwin : : ${INT_CXX} : <cxxflags>\"${INT_CFLAGS} ${INT_CPPFLAGS}\" <linkflags>\"${INT_LDFLAGS} ${INT_CLANG_LDFLAGS}\" <archiver>\"${INT_LIBTOOL}\" <striper>\"${INT_STRIP}\" : ;" > "user-config.jam" - ./b2 -d2 --layout=tagged --build-type=complete --prefix="${PREFIX}" --toolset=darwin-4.2.1 --user-config=user-config.jam variant=release threading=multi link=static install - popd - - export GZIP="-9n" - find prefix | sort | tar --no-recursion -czf osx-depends-${REVISION}.tar.gz -T - - - mv osx-depends-${REVISION}.tar.gz $OUTDIR diff --git a/contrib/gitian-descriptors/gitian-osx-native.yml b/contrib/gitian-descriptors/gitian-osx-native.yml deleted file mode 100644 index a753ad704f..0000000000 --- a/contrib/gitian-descriptors/gitian-osx-native.yml +++ /dev/null @@ -1,178 +0,0 @@ ---- -name: "osx-native" -suites: -- "precise" -architectures: -- "i386" -packages: -- "git-core" -- "automake" -- "faketime" -- "libssl-dev" -- "libbz2-dev" -- "libz-dev" -- "cmake" -- "libcap-dev" -- "p7zip-full" -- "uuid-dev" - -reference_datetime: "2013-06-01 00:00:00" -remotes: [] -files: -- "10cc648683617cca8bcbeae507888099b41b530c.tar.gz" -- "cctools-809.tar.gz" -- "dyld-195.5.tar.gz" -- "ld64-127.2.tar.gz" -- "protobuf-2.5.0.tar.bz2" -- "MacOSX10.7.sdk.tar.gz" -- "cdrkit-1.1.11.tar.gz" -- "libdmg-hfsplus-v0.1.tar.gz" -- "clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz" -- "cdrkit-deterministic.patch" - - -script: | - - echo "18406961fd4a1ec5c7ea35c91d6a80a2f8bb797a2bd243a610bd75e13eff9aca 10cc648683617cca8bcbeae507888099b41b530c.tar.gz" | sha256sum -c - echo "03ba62749b843b131c7304a044a98c6ffacd65b1399b921d69add0375f79d8ad cctools-809.tar.gz" | sha256sum -c - echo "2cf0484c87cf79b606b351a7055a247dae84093ae92c747a74e0cde2c8c8f83c dyld-195.5.tar.gz" | sha256sum -c - echo "97b75547b2bd761306ab3e15ae297f01e7ab9760b922bc657f4ef72e4e052142 ld64-127.2.tar.gz" | sha256sum -c - echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c - echo "d1c030756ecc182defee9fe885638c1785d35a2c2a297b4604c0e0dcc78e47da cdrkit-1.1.11.tar.gz" | sha256sum -c - echo "6569a02eb31c2827080d7d59001869ea14484c281efab0ae7f2b86af5c3120b3 libdmg-hfsplus-v0.1.tar.gz" | sha256sum -c - echo "b9d57a88f9514fa1f327a1a703756d0c1c960f4c58494a5bd80313245d13ffff clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz" | sha256sum -c - echo "cc12bdbd7a09f71cb2a6a3e6ec3e0abe885ca7111c2b47857f5095e5980caf4f cdrkit-deterministic.patch" | sha256sum -c - - - REVISION=r3 - export REFERENCE_DATETIME - export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" - export FAKETIME=$REFERENCE_DATETIME - export TZ=UTC - - REAL_AR=`which ar` - REAL_RANLIB=`which ranlib` - REAL_DATE=`which date` - - echo '#!/bin/bash' > $HOME/ar - echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ar - echo "$REAL_AR \"\$@\"" >> $HOME/ar - - echo '#!/bin/bash' > $HOME/ranlib - echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/ranlib - echo "$REAL_RANLIB \"\$@\"" >> $HOME/ranlib - - echo '#!/bin/bash' > $HOME/date - echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> $HOME/date - echo "$REAL_DATE \"\$@\"" >> $HOME/date - - chmod +x $HOME/ar $HOME/ranlib $HOME/date - - - export PATH=$HOME:$PATH - export SOURCES_PATH=`pwd` - - mkdir -p osx-cross-depends/build - cd osx-cross-depends - - NATIVEPREFIX=`pwd`/native-prefix - BUILD_BASE=`pwd`/build - SDK=`pwd`/SDKs/MacOSX10.7.sdk - HOST=x86_64-apple-darwin11 - MIN_VERSION=10.6 - - CFLAGS="" - CXXFLAGS="${CFLAGS}" - LDFLAGS="-L${NATIVEPREFIX}/lib" - - export PATH=${NATIVEPREFIX}/bin:${PATH} - - mkdir -p ${NATIVEPREFIX}/bin - mkdir -p ${NATIVEPREFIX}/lib - - mkdir -p SDKs - tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz - - # Clang - SOURCE_FILE=${SOURCES_PATH}/clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz - BUILD_DIR=${BUILD_BASE}/clang+llvm-3.2-x86-linux-ubuntu-12.04 - - mkdir -p ${NATIVEPREFIX}/lib/clang/3.2/include - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - cp ${BUILD_DIR}/bin/clang ${NATIVEPREFIX}/bin/ - cp ${BUILD_DIR}/bin/clang++ ${NATIVEPREFIX}/bin/ - cp ${BUILD_DIR}/lib/libLTO.so ${NATIVEPREFIX}/lib/ - cp ${BUILD_DIR}/lib/clang/3.2/include/* ${NATIVEPREFIX}/lib/clang/3.2/include - - # cctools - SOURCE_FILE=${SOURCES_PATH}/10cc648683617cca8bcbeae507888099b41b530c.tar.gz - BUILD_DIR=${BUILD_BASE}/toolchain4-10cc648683617cca8bcbeae507888099b41b530c - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - mkdir -p ${BUILD_DIR}/sdks - pushd ${BUILD_DIR}/sdks; - ln -sf ${SDK} MacOSX10.7.sdk - ln -sf ${SOURCES_PATH}/cctools-809.tar.gz ${BUILD_DIR}/cctools2odcctools/cctools-809.tar.gz - ln -sf ${SOURCES_PATH}/ld64-127.2.tar.gz ${BUILD_DIR}/cctools2odcctools/ld64-127.2.tar.gz - ln -sf ${SOURCES_PATH}/dyld-195.5.tar.gz ${BUILD_DIR}/cctools2odcctools/dyld-195.5.tar.gz - - tar -C ${BUILD_DIR} -xf ${SOURCES_PATH}/clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz - # Hack in the use of our llvm headers rather than grabbing the old llvm-gcc. - sed -i "s|GCC_DIR|LLVM_CLANG_DIR|g" ${BUILD_DIR}/cctools2odcctools/extract.sh - sed -i "s|llvmgcc42-2336.1|clang+llvm-3.2-x86-linux-ubuntu-12.04|g" ${BUILD_DIR}/cctools2odcctools/extract.sh - sed -i "s|\${LLVM_CLANG_DIR}/llvmCore/include/llvm-c|\${LLVM_CLANG_DIR}/include/llvm-c \${LLVM_CLANG_DIR}/include/llvm |" ${BUILD_DIR}/cctools2odcctools/extract.sh - - sed -i "s|fAC_INIT|AC_INIT|" ${BUILD_DIR}/cctools2odcctools/files/configure.ac - sed -i 's/\# Dynamically linked LTO/\t ;\&\n\t linux*)\n# Dynamically linked LTO/' ${BUILD_DIR}/cctools2odcctools/files/configure.ac - - cd ${BUILD_DIR}/cctools2odcctools - ./extract.sh --osxver 10.7 - cd odcctools-809 - ./configure --prefix=${NATIVEPREFIX} --target=${HOST} CFLAGS="${CFLAGS} -I${NATIVEPREFIX}/include -D__DARWIN_UNIX03 -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS" LDFLAGS="${LDFLAGS} -Wl,-rpath=\\\$\$ORIGIN/../lib" --with-sysroot=${SDK} - - # The 'PC' define in sparc/reg.h conflicts but doesn't get used anyway. Just rename it. - sed -i "s|define\tPC|define\tPC_|" ${BUILD_DIR}/cctools2odcctools/odcctools-809/include/architecture/sparc/reg.h - make $MAKEOPTS - make install - popd - - # protoc - SOURCE_FILE=${SOURCES_PATH}/protobuf-2.5.0.tar.bz2 - BUILD_DIR=${BUILD_BASE}/protobuf-2.5.0 - - tar -C ${BUILD_BASE} -xjf ${SOURCE_FILE} - pushd ${BUILD_DIR}; - ./configure --enable-shared=no --disable-dependency-tracking --prefix=${NATIVEPREFIX} - make $MAKEOPTS - cp ${BUILD_DIR}/src/protoc ${NATIVEPREFIX}/bin/ - popd - - # cdrkit - SOURCE_FILE=${SOURCES_PATH}/cdrkit-1.1.11.tar.gz - BUILD_DIR=${BUILD_BASE}/cdrkit-1.1.11 - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - pushd ${BUILD_DIR} - patch -p1 < ${SOURCES_PATH}/cdrkit-deterministic.patch - cmake -DCMAKE_INSTALL_PREFIX=${NATIVEPREFIX} - make $MAKEOPTS genisoimage - make -C genisoimage install - popd - - # libdmg-hfsplus - SOURCE_FILE=${SOURCES_PATH}/libdmg-hfsplus-v0.1.tar.gz - BUILD_DIR=${BUILD_BASE}/libdmg-hfsplus-libdmg-hfsplus-v0.1 - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - mkdir -p ${BUILD_DIR}/build - pushd ${BUILD_DIR}/build - cmake -DCMAKE_INSTALL_PREFIX:PATH=${NATIVEPREFIX}/bin .. - make $MAKEOPTS - make install - popd - - rm -rf native-prefix/docs - - export GZIP="-9n" - find native-prefix | sort | tar --no-recursion -czf osx-native-depends-$REVISION.tar.gz -T - - mv osx-native-depends-$REVISION.tar.gz $OUTDIR diff --git a/contrib/gitian-descriptors/gitian-osx-qt.yml b/contrib/gitian-descriptors/gitian-osx-qt.yml deleted file mode 100644 index 5e0ad9222a..0000000000 --- a/contrib/gitian-descriptors/gitian-osx-qt.yml +++ /dev/null @@ -1,186 +0,0 @@ ---- -name: "osx-qt" -suites: -- "precise" -architectures: -- "i386" -packages: -- "git-core" -- "automake" -- "p7zip-full" - -reference_datetime: "2013-06-01 00:00:00" -remotes: [] -files: -- "qt-everywhere-opensource-src-5.2.1.tar.gz" -- "osx-native-depends-r3.tar.gz" -- "osx-depends-r4.tar.gz" -- "MacOSX10.7.sdk.tar.gz" - -script: | - - echo "84e924181d4ad6db00239d87250cc89868484a14841f77fb85ab1f1dbdcd7da1 qt-everywhere-opensource-src-5.2.1.tar.gz" | sha256sum -c - - REVISION=r4 - export SOURCES_PATH=`pwd` - export TAR_OPTIONS="-m --mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" - export ZERO_AR_DATE=1 - - export TZ=UTC - - REAL_DATE=`which date` - echo '#!/bin/bash' > $HOME/date - echo "$REAL_DATE -d \"${REFERENCE_DATETIME}\" \"\$@\"" >> $HOME/date - - chmod +x $HOME/date - export PATH=$HOME:$PATH - - mkdir -p osx-cross-depends/build - cd osx-cross-depends - - PREFIX=`pwd`/prefix - NATIVEPREFIX=`pwd`/native-prefix - BUILD_BASE=`pwd`/build - SDK=`pwd`/SDKs/MacOSX10.7.sdk - HOST=x86_64-apple-darwin11 - MIN_VERSION=10.6 - - INT_CFLAGS="-target ${HOST} -mmacosx-version-min=${MIN_VERSION} --sysroot ${SDK} -msse2 -Qunused-arguments" - INT_CXXFLAGS="${INT_CFLAGS}" - INT_LDFLAGS="-L${PREFIX}/lib -L${SDK}/usr/lib/i686-apple-darwin10/4.2.1" - INT_LDFLAGS_CLANG="-B${NATIVEPREFIX}/bin" - INT_CPPFLAGS="-I${PREFIX}/include" - INT_CC=clang - INT_CXX=clang++ - INT_OBJC=clang - INT_OBJCXX=clang++ - INT_AR=${HOST}-ar - INT_RANLIB=${HOST}-ranlib - INT_LIBTOOL=${HOST}-libtool - INT_INSTALL_NAME_TOOL=${HOST}-install_name_tool - - export PATH=${NATIVEPREFIX}/bin:${PATH} - - mkdir -p ${NATIVEPREFIX}/bin - mkdir -p ${NATIVEPREFIX}/lib - mkdir -p ${PREFIX}/bin - mkdir -p ${PREFIX}/lib - mkdir -p ${BUILD_BASE} - - mkdir -p SDKs - tar -C SDKs -xf ${SOURCES_PATH}/MacOSX10.7.sdk.tar.gz - - tar xf /home/ubuntu/build/osx-native-depends-r3.tar.gz - - export PATH=`pwd`/native-prefix/bin:$PATH - tar xf /home/ubuntu/build/osx-depends-r4.tar.gz - - SOURCE_FILE=${SOURCES_PATH}/qt-everywhere-opensource-src-5.2.1.tar.gz - BUILD_DIR=${BUILD_BASE}/qt-everywhere-opensource-src-5.2.1 - - - tar -C ${BUILD_BASE} -xf ${SOURCE_FILE} - - # Install our mkspec. All files are pulled from the macx-clang spec, except for - # our custom qmake.conf - SPECFILE=${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/qmake.conf - - mkdir -p ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux - cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/Info.plist.lib ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/ - cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/Info.plist.app ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/ - cp -f ${BUILD_DIR}/qtbase/mkspecs/macx-clang/qplatformdefs.h ${BUILD_DIR}/qtbase/mkspecs/macx-clang-linux/ - - cat > ${SPECFILE} <<ENDCONF - - MAKEFILE_GENERATOR = UNIX - CONFIG += app_bundle incremental global_init_link_order lib_version_first plugin_no_soname absolute_library_soname - QMAKE_INCREMENTAL_STYLE = sublib - - include(../common/macx.conf) - include(../common/gcc-base-mac.conf) - include(../common/clang.conf) - include(../common/clang-mac.conf) - - QMAKE_XCODE_VERSION=4.3 - QMAKE_XCODE_DEVELOPER_PATH=/Developer - - QMAKE_MACOSX_DEPLOYMENT_TARGET = ${MIN_VERSION} - - QMAKE_MAC_SDK=macosx - QMAKE_MAC_SDK.macosx.path = ${SDK} - QMAKE_MAC_SDK.macosx.platform_name = macosx - QMAKE_MAC_SDK_PATH=${SDK} - - QMAKE_CFLAGS += -target ${HOST} - QMAKE_OBJECTIVE_CFLAGS += -target ${HOST} - QMAKE_CXXFLAGS += -target ${HOST} - - QMAKE_LFLAGS += -target ${HOST} - QMAKE_AR = ${HOST}-ar cq - QMAKE_RANLIB=${HOST}-ranlib - QMAKE_LIBTOOL=${HOST}-libtool - QMAKE_INSTALL_NAME_TOOL=${HOST}-install_name_tool - - load(qt_config) - - ENDCONF - - pushd ${BUILD_DIR} - ./configure -release -opensource -openssl-linked \ - -no-audio-backend -no-javascript-jit -no-sql-sqlite -no-sql-tds \ - -no-cups -no-iconv -no-dbus -no-gif -no-audio-backend -no-freetype \ - -no-javascript-jit -no-sql-sqlite -no-nis -no-cups -no-iconv -no-pch \ - -no-dbus -no-gif -no-sm -nomake examples -no-feature-style-plastique \ - -no-xcb -no-qml-debug -no-pch -no-nis \ - -no-feature-style-cde -no-feature-style-s60 -no-feature-style-motif \ - -no-feature-style-windowsmobile -no-feature-style-windowsce \ - -no-feature-style-cleanlooks \ - -no-sql-db2 -no-sql-ibase -no-sql-oci -no-sql-tds -no-sql-mysql \ - -no-sql-odbc -no-sql-psql -no-sql-sqlite -no-sql-sqlite2 \ - -skip qtsvg -skip qtwebkit -skip qtwebkit-examples -skip qtserialport \ - -skip qtdeclarative -skip qtmultimedia -skip qtimageformats \ - -skip qtlocation -skip qtsensors -skip qtquick1 -skip qtxmlpatterns \ - -skip qtquickcontrols -skip qtactiveqt -skip qtconnectivity \ - -skip qtwinextras -skip qtscript \ - -prefix ${PREFIX} -bindir ${NATIVEPREFIX}/bin \ - -confirm-license -xplatform macx-clang-linux -v ${INT_LDFLAGS} - - # RCC's output is sorted using each file entry's hash as the key. Unfortunately, - # the hash function uses a random seed for each run so the results aren't - # deterministic. This leads to static resources being defined in a random order, - # which in-turn means that object files are not predictable. - # Fortunately, this upsets Qt's unit tests as well, so they've added the - # QT_RCC_TEST environment variable to set a pre-defined seed. Here, do the same - # thing for the same reason. - QT_RCC_TEST=1 make $MAKEOPTS module-qtbase-make_first - - - make $MAKEOPTS module-qttranslations-make_first - make $MAKEOPTS module-qttools-make_first - make $MAKEOPTS -C qtbase - make -C qtbase install - make -C qttranslations install - make -C qttools/src/linguist install - popd - - # This file should not be installed to the destination. It's native and - # non-deterministic. Remove it. - # See: https://bugreports.qt-project.org/browse/QTBUG-31393 - rm -f ${PREFIX}/lib/libQt5Bootstrap.a - - rm -f ${PREFIX}/lib/Qt*.framework/Qt*.prl - pushd ${PREFIX}/include - ln -sf ../lib/QtNetwork.framework/Headers/ QtNetwork - ln -sf ../lib/QtWidgets.framework/Headers/ QtWidgets - ln -sf ../lib/QtGui.framework/Headers/ QtGui - ln -sf ../lib/QtCore.framework/Headers/ QtCore - ln -sf ../lib/QtTest.framework/Headers/ QtTest - popd - - rm -f ${PREFIX}/lib/*.la - find ${PREFIX}/lib -name "*.prl" -delete - - export GZIP="-9n" - find native-prefix prefix | sort | tar --no-recursion -czf osx-depends-qt-5.2.1-${REVISION}.tar.gz -T - - - mv osx-depends-qt-5.2.1-${REVISION}.tar.gz $OUTDIR diff --git a/contrib/gitian-descriptors/gitian-osx.yml b/contrib/gitian-descriptors/gitian-osx.yml new file mode 100644 index 0000000000..7ec0700ed3 --- /dev/null +++ b/contrib/gitian-descriptors/gitian-osx.yml @@ -0,0 +1,114 @@ +--- +name: "bitcoin-osx-0.10" +enable_cache: true +suites: +- "precise" +architectures: +- "amd64" +packages: +- "g++-multilib" +- "git-core" +- "pkg-config" +- "autoconf2.13" +- "libtool" +- "automake" +- "faketime" +- "bsdmainutils" +- "cmake" +- "libcap-dev" +- "libz-dev" +- "libbz2-dev" +reference_datetime: "2013-06-01 00:00:00" +remotes: +- "url": "https://github.com/bitcoin/bitcoin.git" + "dir": "bitcoin" +files: +- "MacOSX10.7.sdk.tar.gz" +script: | + WRAP_DIR=$HOME/wrapped + HOSTS="x86_64-apple-darwin11" + CONFIGFLAGS="--enable-upnp-default GENISOIMAGE=$WRAP_DIR/genisoimage" + FAKETIME_HOST_PROGS="" + FAKETIME_PROGS="ar ranlib date dmg genisoimage" + + export QT_RCC_TEST=1 + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + export ZERO_AR_DATE=1 + + # Create global faketime wrappers + for prog in ${FAKETIME_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + + # Create per-host faketime wrappers + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + export PATH=${WRAP_DIR}:${PATH} + + cd bitcoin + BASEPREFIX=`pwd`/depends + + mkdir -p ${BASEPREFIX}/SDKs + tar -C ${BASEPREFIX}/SDKs -xf ${BUILD_DIR}/MacOSX10.7.sdk.tar.gz + + # Build dependencies for each host + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + done + + # Create the release tarball using (arbitrarily) the first host + ./autogen.sh + ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` + make dist + DISTNAME=`echo bitcoin-*.tar.gz` + + # Correct tar file order + mkdir -p temp + pushd temp + tar xf ../$DISTNAME + find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$DISTNAME + popd + + ORIGPATH="$PATH" + # Extract the release tarball into a dir for each host and build + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir -p distsrc-${i} + cd distsrc-${i} + tar --strip-components=1 -xf ../$DISTNAME + + ./configure --prefix=${BASEPREFIX}/${i} --bindir=${OUTDIR}/${i}/bin --includedir=${OUTDIR}/${i}/include --libdir=${OUTDIR}/${i}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + make ${MAKEOPTS} + make install-strip + make deploy + ${WRAP_DIR}/dmg dmg Bitcoin-Qt.dmg ${OUTDIR}/Bitcoin-Qt.dmg + cd .. + done + mkdir -p $OUTDIR/src + mv $DISTNAME $OUTDIR/src + + # Delete unwanted stuff + find ${OUTDIR} -name "lib*.la" -delete diff --git a/contrib/gitian-descriptors/gitian-win.yml b/contrib/gitian-descriptors/gitian-win.yml index b2795c5376..172807467a 100644 --- a/contrib/gitian-descriptors/gitian-win.yml +++ b/contrib/gitian-descriptors/gitian-win.yml @@ -1,97 +1,108 @@ --- -name: "bitcoin" +name: "bitcoin-win-0.10" +enable_cache: true suites: - "precise" architectures: - "amd64" -packages: -- "mingw-w64" -- "g++-mingw-w64" +packages: +- "g++" - "git-core" -- "unzip" -- "nsis" -- "faketime" +- "pkg-config" - "autoconf2.13" - "libtool" - "automake" -- "pkg-config" +- "faketime" - "bsdmainutils" - +- "mingw-w64" +- "g++-mingw-w64" +- "nsis" reference_datetime: "2013-06-01 00:00:00" remotes: - "url": "https://github.com/bitcoin/bitcoin.git" "dir": "bitcoin" -files: -- "qt-win32-5.2.0-gitian-r3.zip" -- "qt-win64-5.2.0-gitian-r3.zip" -- "boost-win32-1.55.0-gitian-r6.zip" -- "boost-win64-1.55.0-gitian-r6.zip" -- "bitcoin-deps-win32-gitian-r13.zip" -- "bitcoin-deps-win64-gitian-r13.zip" -- "protobuf-win32-2.5.0-gitian-r4.zip" -- "protobuf-win64-2.5.0-gitian-r4.zip" +files: [] script: | - # Defines - export TZ=UTC - INDIR=$HOME/build - OPTFLAGS='-O2' - TEMPDIR="$HOME/tempdir" - NEEDDIST=1 - # Qt: workaround for determinism in resource ordering - # Qt5's rcc uses a QHash to store the files for the resource. - # A security fix in QHash makes the ordering of keys to be different on every run - # (https://qt.gitorious.org/qt/qtbase/commit/c01eaa438200edc9a3bbcd8ae1e8ded058bea268). - # This is good in general but qrc shouldn't be doing a traversal over a randomized container. - # The thorough solution would be to use QMap instead of QHash, but this requires patching Qt. - # For now luckily there is a test mode that forces a fixed seed. + WRAP_DIR=$HOME/wrapped + HOSTS="x86_64-w64-mingw32 i686-w64-mingw32" + CONFIGFLAGS="--enable-upnp-default" + FAKETIME_HOST_PROGS="g++ ar ranlib nm windres strip" + FAKETIME_PROGS="date makensis" + export QT_RCC_TEST=1 - for BITS in 32 64; do # for architectures - # - STAGING=$HOME/staging${BITS} - BUILDDIR=$HOME/build${BITS} - BINDIR=$OUTDIR/$BITS - if [ "x$BITS" = "x32" ]; then - HOST=i686-w64-mingw32 - else - HOST=x86_64-w64-mingw32 - fi - export PATH=$STAGING/host/bin:$PATH - mkdir -p $STAGING $BUILDDIR $BINDIR - # - cd $STAGING - unzip $INDIR/qt-win${BITS}-5.2.0-gitian-r3.zip - unzip $INDIR/boost-win${BITS}-1.55.0-gitian-r6.zip - unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r13.zip - unzip $INDIR/protobuf-win${BITS}-2.5.0-gitian-r4.zip - if [ "x$NEEDDIST" = "x1" ]; then - # Make source code archive which is architecture independent so it only needs to be done once - cd $HOME/build/bitcoin - ./autogen.sh - ./configure --bindir=$OUTDIR --prefix=$STAGING --host=$HOST --with-qt-plugindir=$STAGING/plugins --with-qt-incdir=$STAGING/include --with-qt-bindir=$STAGING/host/bin --with-boost=$STAGING --disable-maintainer-mode --with-protoc-bindir=$STAGING/host/bin --disable-dependency-tracking CPPFLAGS="-I$STAGING/include ${OPTFLAGS}" LDFLAGS="-L$STAGING/lib ${OPTFLAGS}" CXXFLAGS="-frandom-seed=bitcoin ${OPTFLAGS}" - make dist - DISTNAME=`echo bitcoin-*.tar.gz` - NEEDDIST=0 - fi - # Build platform-dependent executables from source archive - cd $BUILDDIR - mkdir -p distsrc - cd distsrc - tar --strip-components=1 -xf $HOME/build/bitcoin/$DISTNAME - ./configure --enable-upnp-default --bindir=$BINDIR --prefix=$STAGING --host=$HOST --with-qt-plugindir=$STAGING/plugins --with-qt-incdir=$STAGING/include --with-qt-bindir=$STAGING/host/bin --with-boost=$STAGING --disable-maintainer-mode --with-protoc-bindir=$STAGING/host/bin --disable-dependency-tracking CPPFLAGS="-I$STAGING/include ${OPTFLAGS}" LDFLAGS="-L$STAGING/lib ${OPTFLAGS}" CXXFLAGS="-frandom-seed=bitcoin ${OPTFLAGS}" - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - make $MAKEOPTS + export GZIP="-9n" + export TAR_OPTIONS="--mtime="$REFERENCE_DATE\\\ $REFERENCE_TIME"" + export TZ="UTC" + export BUILD_DIR=`pwd` + mkdir -p ${WRAP_DIR} + if test -n "$GBUILD_CACHE_ENABLED"; then + export SOURCES_PATH=${GBUILD_COMMON_CACHE} + export BASE_CACHE=${GBUILD_PACKAGE_CACHE} + mkdir -p ${BASE_CACHE} ${SOURCES_PATH} + fi + + # Create global faketime wrappers + for prog in ${FAKETIME_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${prog} + echo "REAL=\`which -a ${prog} | grep -v ${WRAP_DIR}/${prog} | head -1\`" >> ${WRAP_DIR}/${prog} + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${prog} + chmod +x ${WRAP_DIR}/${prog} + done + + # Create per-host faketime wrappers + for i in $HOSTS; do + for prog in ${FAKETIME_HOST_PROGS}; do + echo '#!/bin/bash' > ${WRAP_DIR}/${i}-${prog} + echo "REAL=\`which -a ${i}-${prog} | grep -v ${WRAP_DIR}/${i}-${prog} | head -1\`" >> ${WRAP_DIR}/${i}-${prog} + echo 'export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1' >> ${WRAP_DIR}/${i}-${prog} + echo "export FAKETIME=\"${REFERENCE_DATETIME}\"" >> ${WRAP_DIR}/${i}-${prog} + echo "\$REAL \$@" >> $WRAP_DIR/${i}-${prog} + chmod +x ${WRAP_DIR}/${i}-${prog} + done + done + export PATH=${WRAP_DIR}:${PATH} + + cd bitcoin + BASEPREFIX=`pwd`/depends + # Build dependencies for each host + for i in $HOSTS; do + make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" + done + + # Create the release tarball using (arbitrarily) the first host + ./autogen.sh + ./configure --prefix=${BASEPREFIX}/`echo "${HOSTS}" | awk '{print $1;}'` + make dist + DISTNAME=`echo bitcoin-*.tar.gz` + + # Correct tar file order + mkdir -p temp + pushd temp + tar xf ../$DISTNAME + find bitcoin-* | sort | tar --no-recursion -c -T - | gzip -9n > ../$DISTNAME + popd + + ORIGPATH="$PATH" + # Extract the release tarball into a dir for each host and build + for i in ${HOSTS}; do + export PATH=${BASEPREFIX}/${i}/native/bin:${ORIGPATH} + mkdir -p distsrc-${i} + cd distsrc-${i} + tar --strip-components=1 -xf ../$DISTNAME + + ./configure --prefix=${BASEPREFIX}/${i} --bindir=${OUTDIR}/${i}/bin --includedir=${OUTDIR}/${i}/include --libdir=${OUTDIR}/${i}/lib --disable-ccache --disable-maintainer-mode --disable-dependency-tracking ${CONFIGFLAGS} + make ${MAKEOPTS} make deploy make install-strip - cp -f bitcoin-*setup*.exe $BINDIR/ - unset LD_PRELOAD - unset FAKETIME - done # for BITS in - - # sort distribution tar file and normalize user/group/mtime information for deterministic output + cp -f bitcoin-*setup*.exe $OUTDIR/ + cd .. + done mkdir -p $OUTDIR/src - rm -rf $TEMPDIR - mkdir -p $TEMPDIR - cd $TEMPDIR - tar -xvf $HOME/build/bitcoin/$DISTNAME | sort | tar --no-recursion -cT /dev/stdin --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 --mtime="$REFERENCE_DATETIME" | gzip -n > $OUTDIR/src/$DISTNAME + mv $DISTNAME $OUTDIR/src + mv ${OUTDIR}/x86_64-* ${OUTDIR}/64 + mv ${OUTDIR}/i686-* ${OUTDIR}/32 + # Delete unwanted stuff + find ${OUTDIR} -name "lib*.la" -delete diff --git a/contrib/gitian-descriptors/protobuf-win.yml b/contrib/gitian-descriptors/protobuf-win.yml deleted file mode 100644 index 1b7af08843..0000000000 --- a/contrib/gitian-descriptors/protobuf-win.yml +++ /dev/null @@ -1,65 +0,0 @@ ---- -name: "protobuf-win32" -suites: -- "precise" -architectures: -- "amd64" -packages: -- "mingw-w64" -- "g++-mingw-w64" -- "zip" -- "faketime" -reference_datetime: "2013-04-15 00:00:00" -remotes: [] -files: -- "protobuf-2.5.0.tar.bz2" -script: | - # - export TZ=UTC - INDIR=$HOME/build - TEMPDIR=$HOME/tmp - OPTFLAGS="-O2" - # Integrity Check - echo "13bfc5ae543cf3aa180ac2485c0bc89495e3ae711fc6fab4f8ffe90dfb4bb677 protobuf-2.5.0.tar.bz2" | sha256sum -c - - for BITS in 32 64; do # for architectures - # - INSTALLPREFIX=$HOME/staging${BITS} - BUILDDIR=$HOME/build${BITS} - if [ "x$BITS" = "x32" ]; then - HOST=i686-w64-mingw32 - else - HOST=x86_64-w64-mingw32 - fi - # - mkdir -p $INSTALLPREFIX $BUILDDIR - cd $BUILDDIR - # - tar xjf $INDIR/protobuf-2.5.0.tar.bz2 - cd protobuf-2.5.0 - # First: build a native (linux) protoc - ./configure --enable-shared=no --disable-dependency-tracking --without-zlib CXXFLAGS="-frandom-seed=11 ${OPTFLAGS}" - make - mkdir -p $INSTALLPREFIX/host/bin - cp src/protoc $INSTALLPREFIX/host/bin - # Now recompile with the mingw cross-compiler: - make distclean - ./configure --prefix=$INSTALLPREFIX --enable-shared=no --disable-dependency-tracking --without-zlib --with-protoc=$INSTALLPREFIX/host/bin/protoc --host=$HOST CXXFLAGS="-frandom-seed=11 ${OPTFLAGS}" - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - make - make install - # post-process all generated libraries to be deterministic - # extract them to a temporary directory then re-build them deterministically - for LIB in $(find $INSTALLPREFIX -name \*.a); do - rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR - $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt - rm $LIB - $HOST-ar crsD $LIB $(cat /tmp/list.txt) - done - # - cd $INSTALLPREFIX - find include lib host | sort | zip -X@ $OUTDIR/protobuf-win$BITS-2.5.0-gitian-r4.zip - unset LD_PRELOAD - unset FAKETIME - done # for BITS in diff --git a/contrib/gitian-descriptors/qt-linux.yml b/contrib/gitian-descriptors/qt-linux.yml deleted file mode 100644 index fd86b4df1d..0000000000 --- a/contrib/gitian-descriptors/qt-linux.yml +++ /dev/null @@ -1,264 +0,0 @@ ---- -name: "qt-linux" -suites: -- "precise" -architectures: -- "i386" -- "amd64" -packages: -- "zip" -- "unzip" -- "faketime" -- "unzip" -- "libxext-dev" -reference_datetime: "2011-01-30 00:00:00" -remotes: [] -files: -- "qt-everywhere-opensource-src-4.6.4.tar.gz" -script: | - export FAKETIME=$REFERENCE_DATETIME - export TZ=UTC - if [ "x$GBUILD_BITS" = "x32" ]; then - ARCH='i386-linux-gnu' - else - ARCH='x86_64-linux-gnu' - fi - # The purpose of this gitian build is not to actually build Qt, but to export - # the headers as well as pkgconfig files in a useable format so that we can - # pretend to link against an older version. The goal is to link to the - # system version of Qt 4. - # Also build development tools. - INSTALLPREFIX="$HOME/install" - # Integrity Check - echo "9ad4d46c721b53a429ed5a2eecfd3c239a9ab566562f183f99d3125f1a234250 qt-everywhere-opensource-src-4.6.4.tar.gz" | sha256sum -c - # Make install directories - mkdir -p $INSTALLPREFIX - mkdir -p $INSTALLPREFIX/include - PKGCONFIGDIR=$INSTALLPREFIX/lib/pkgconfig - mkdir -p $PKGCONFIGDIR - # - tar xzf qt-everywhere-opensource-src-4.6.4.tar.gz - cd qt-everywhere-opensource-src-4.6.4 - QTBUILDDIR=$(pwd) - sed 's/TODAY=`date +%Y-%m-%d`/TODAY=2011-01-30/' -i configure - - # Need to build 4.6-versioned host utilities as well (lrelease/qrc/lupdate/...) - ./configure -prefix $INSTALLPREFIX -confirm-license -release -opensource -no-qt3support -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-declarative -no-script -no-scripttools -no-javascript-jit -no-webkit -no-svg -no-xmlpatterns -no-sql-sqlite -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-libtiff -no-opengl -nomake examples -nomake demos -nomake docs - # - make $MAKEOPTS -C src/tools install # (rcc, uic, moc) - make $MAKEOPTS -C tools/linguist/lrelease install # (lrelease) - # install includes and pkgconfig files - for DIR in src/corelib src/gui src/testlib src/dbus src/network; do - ( - cd $DIR - # extract module (QtCore/QtNetwork/...) from Makefile - MODULE=$(grep "QMAKE_TARGET *=" Makefile | cut -d = -f 2 | xargs) - # patch makefile so that not everything is build first - sed -i 's/first: all/first:/g' Makefile - make install_flat_headers install_class_headers install_targ_headers - # create and install pkgconfig descriptor - make ../../lib/pkgconfig/$MODULE.pc - sed -e "s,$QTBUILDDIR,$INSTALLPREFIX,g" ../../lib/pkgconfig/$MODULE.pc > $PKGCONFIGDIR/$MODULE.pc - # create links to existing Qt libraries - ln -sf /usr/lib/${ARCH}/lib${MODULE}.so.4 ${INSTALLPREFIX}/lib/lib${MODULE}.so - ) - done - - # Write our own configuration header, same as Ubuntu - # When we don't do this, the configuration will be without STL support (the QString from/to stdString methods) - QCONFIG=$INSTALLPREFIX/include/Qt/qconfig.h - echo ' - /* Qt Edition */ - #ifndef QT_EDITION - # define QT_EDITION QT_EDITION_OPENSOURCE - #endif - ' > $QCONFIG - - if [ "x$GBUILD_BITS" = "x32" ]; then - echo ' - /* Machine byte-order */ - #define Q_BIG_ENDIAN 4321 - #define Q_LITTLE_ENDIAN 1234 - #define QT_BUILD_KEY "i386 linux g++-4 full-config" - #define QT_BUILD_KEY_COMPAT "i686 Linux g++-4 full-config" - - #ifdef QT_BOOTSTRAPPED - #define Q_BYTE_ORDER Q_LITTLE_ENDIAN - #else - #define Q_BYTE_ORDER Q_LITTLE_ENDIAN - #endif - /* Machine Architecture */ - #ifndef QT_BOOTSTRAPPED - # define QT_ARCH_I386 - #else - # define QT_ARCH_I386 - #endif - /* Compile time features */ - #define QT_LARGEFILE_SUPPORT 64 - #define QT_POINTER_SIZE 4 - ' >> $QCONFIG - else - echo ' - /* Machine byte-order */ - #define Q_BIG_ENDIAN 4321 - #define Q_LITTLE_ENDIAN 1234 - #define QT_BUILD_KEY "x86_64 linux g++-4 full-config" - #define QT_BUILD_KEY_COMPAT "x86_64 Linux g++-4 full-config" - - #ifdef QT_BOOTSTRAPPED - #define Q_BYTE_ORDER Q_LITTLE_ENDIAN - #else - #define Q_BYTE_ORDER Q_LITTLE_ENDIAN - #endif - /* Machine Architecture */ - #ifndef QT_BOOTSTRAPPED - # define QT_ARCH_X86_64 - #else - # define QT_ARCH_X86_64 - #endif - /* Compile time features */ - #define QT_LARGEFILE_SUPPORT 64 - #define QT_POINTER_SIZE 8 - ' >> $QCONFIG - fi - - echo ' - #ifndef QT_BOOTSTRAPPED - - #if defined(QT_NO_EGL) && defined(QT_EGL) - # undef QT_NO_EGL - #elif !defined(QT_NO_EGL) && !defined(QT_EGL) - # define QT_NO_EGL - #endif - - #if defined(QT_NO_GSTREAMER) && defined(QT_GSTREAMER) - # undef QT_NO_GSTREAMER - #elif !defined(QT_NO_GSTREAMER) && !defined(QT_GSTREAMER) - # define QT_NO_GSTREAMER - #endif - - #if defined(QT_NO_ICD) && defined(QT_ICD) - # undef QT_NO_ICD - #elif !defined(QT_NO_ICD) && !defined(QT_ICD) - # define QT_NO_ICD - #endif - - #if defined(QT_NO_IMAGEFORMAT_JPEG) && defined(QT_IMAGEFORMAT_JPEG) - # undef QT_NO_IMAGEFORMAT_JPEG - #elif !defined(QT_NO_IMAGEFORMAT_JPEG) && !defined(QT_IMAGEFORMAT_JPEG) - # define QT_NO_IMAGEFORMAT_JPEG - #endif - - #if defined(QT_NO_IMAGEFORMAT_MNG) && defined(QT_IMAGEFORMAT_MNG) - # undef QT_NO_IMAGEFORMAT_MNG - #elif !defined(QT_NO_IMAGEFORMAT_MNG) && !defined(QT_IMAGEFORMAT_MNG) - # define QT_NO_IMAGEFORMAT_MNG - #endif - - #if defined(QT_NO_IMAGEFORMAT_TIFF) && defined(QT_IMAGEFORMAT_TIFF) - # undef QT_NO_IMAGEFORMAT_TIFF - #elif !defined(QT_NO_IMAGEFORMAT_TIFF) && !defined(QT_IMAGEFORMAT_TIFF) - # define QT_NO_IMAGEFORMAT_TIFF - #endif - - #if defined(QT_NO_MULTIMEDIA) && defined(QT_MULTIMEDIA) - # undef QT_NO_MULTIMEDIA - #elif !defined(QT_NO_MULTIMEDIA) && !defined(QT_MULTIMEDIA) - # define QT_NO_MULTIMEDIA - #endif - - #if defined(QT_NO_OPENVG) && defined(QT_OPENVG) - # undef QT_NO_OPENVG - #elif !defined(QT_NO_OPENVG) && !defined(QT_OPENVG) - # define QT_NO_OPENVG - #endif - - #if defined(QT_NO_PHONON) && defined(QT_PHONON) - # undef QT_NO_PHONON - #elif !defined(QT_NO_PHONON) && !defined(QT_PHONON) - # define QT_NO_PHONON - #endif - - #if defined(QT_NO_PULSEAUDIO) && defined(QT_PULSEAUDIO) - # undef QT_NO_PULSEAUDIO - #elif !defined(QT_NO_PULSEAUDIO) && !defined(QT_PULSEAUDIO) - # define QT_NO_PULSEAUDIO - #endif - - #if defined(QT_NO_S60) && defined(QT_S60) - # undef QT_NO_S60 - #elif !defined(QT_NO_S60) && !defined(QT_S60) - # define QT_NO_S60 - #endif - - #if defined(QT_NO_STYLE_S60) && defined(QT_STYLE_S60) - # undef QT_NO_STYLE_S60 - #elif !defined(QT_NO_STYLE_S60) && !defined(QT_STYLE_S60) - # define QT_NO_STYLE_S60 - #endif - - #if defined(QT_NO_SXE) && defined(QT_SXE) - # undef QT_NO_SXE - #elif !defined(QT_NO_SXE) && !defined(QT_SXE) - # define QT_NO_SXE - #endif - - #if defined(QT_NO_WEBKIT) && defined(QT_WEBKIT) - # undef QT_NO_WEBKIT - #elif !defined(QT_NO_WEBKIT) && !defined(QT_WEBKIT) - # define QT_NO_WEBKIT - #endif - - #if defined(QT_NO_ZLIB) && defined(QT_ZLIB) - # undef QT_NO_ZLIB - #elif !defined(QT_NO_ZLIB) && !defined(QT_ZLIB) - # define QT_NO_ZLIB - #endif - - #if defined(QT_RUNTIME_XCURSOR) && defined(QT_NO_RUNTIME_XCURSOR) - # undef QT_RUNTIME_XCURSOR - #elif !defined(QT_RUNTIME_XCURSOR) && !defined(QT_NO_RUNTIME_XCURSOR) - # define QT_RUNTIME_XCURSOR - #endif - - #if defined(QT_RUNTIME_XFIXES) && defined(QT_NO_RUNTIME_XFIXES) - # undef QT_RUNTIME_XFIXES - #elif !defined(QT_RUNTIME_XFIXES) && !defined(QT_NO_RUNTIME_XFIXES) - # define QT_RUNTIME_XFIXES - #endif - - #if defined(QT_RUNTIME_XINERAMA) && defined(QT_NO_RUNTIME_XINERAMA) - # undef QT_RUNTIME_XINERAMA - #elif !defined(QT_RUNTIME_XINERAMA) && !defined(QT_NO_RUNTIME_XINERAMA) - # define QT_RUNTIME_XINERAMA - #endif - - #if defined(QT_RUNTIME_XINPUT) && defined(QT_NO_RUNTIME_XINPUT) - # undef QT_RUNTIME_XINPUT - #elif !defined(QT_RUNTIME_XINPUT) && !defined(QT_NO_RUNTIME_XINPUT) - # define QT_RUNTIME_XINPUT - #endif - - #if defined(QT_RUNTIME_XRANDR) && defined(QT_NO_RUNTIME_XRANDR) - # undef QT_RUNTIME_XRANDR - #elif !defined(QT_RUNTIME_XRANDR) && !defined(QT_NO_RUNTIME_XRANDR) - # define QT_RUNTIME_XRANDR - #endif - - #if defined(QT_USE_MATH_H_FLOATS) && defined(QT_NO_USE_MATH_H_FLOATS) - # undef QT_USE_MATH_H_FLOATS - #elif !defined(QT_USE_MATH_H_FLOATS) && !defined(QT_NO_USE_MATH_H_FLOATS) - # define QT_USE_MATH_H_FLOATS - #endif - - #endif // QT_BOOTSTRAPPED - - #define QT_VISIBILITY_AVAILABLE - ' >> $QCONFIG - cp $QCONFIG $INSTALLPREFIX/include/QtCore/qconfig.h - - cd $INSTALLPREFIX - # as zip stores file timestamps, use faketime to intercept stat calls to set dates for all files to reference date - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - # Create a .tar.gz because .zip has problems with symbolic links - find | sort | tar --no-recursion -cT /dev/stdin --mode='u+rw,go+r-w,a+X' --owner=0 --group=0 --mtime="$REFERENCE_DATETIME" | gzip -n > $OUTDIR/qt-linux${GBUILD_BITS}-4.6.4-gitian-r1.tar.gz diff --git a/contrib/gitian-descriptors/qt-win.yml b/contrib/gitian-descriptors/qt-win.yml deleted file mode 100644 index 57bc4c3180..0000000000 --- a/contrib/gitian-descriptors/qt-win.yml +++ /dev/null @@ -1,92 +0,0 @@ ---- -name: "qt" -suites: -- "precise" -architectures: -- "amd64" -packages: -- "mingw-w64" -- "g++-mingw-w64" -- "zip" -- "unzip" -- "faketime" -- "libz-dev" -reference_datetime: "2011-01-30 00:00:00" -remotes: [] -files: -- "qt-everywhere-opensource-src-5.2.0.tar.gz" -- "bitcoin-deps-win32-gitian-r13.zip" -- "bitcoin-deps-win64-gitian-r13.zip" -script: | - # Defines - export TZ=UTC - INDIR=$HOME/build - TEMPDIR=$HOME/tmp - # Qt: workaround for determinism in resource ordering - # Qt5's rcc uses a QHash to store the files for the resource. - # A security fix in QHash makes the ordering of keys to be different on every run - # (https://qt.gitorious.org/qt/qtbase/commit/c01eaa438200edc9a3bbcd8ae1e8ded058bea268). - # This is good in general but qrc shouldn't be doing a traversal over a randomized container. - # The thorough solution would be to use QMap instead of QHash, but this requires patching Qt. - # For now luckily there is a test mode that forces a fixed seed. - export QT_RCC_TEST=1 - # Integrity Check - echo "395ec72277c5786c65b8163ef5817fd03d0a1f524a6d47f53624baf8056f1081 qt-everywhere-opensource-src-5.2.0.tar.gz" | sha256sum -c - - for BITS in 32 64; do # for architectures - # - INSTALLPREFIX=$HOME/staging${BITS} - BUILDDIR=$HOME/build${BITS} - DEPSDIR=$HOME/deps${BITS} - if [ "x$BITS" = "x32" ]; then - HOST=i686-w64-mingw32 - else - HOST=x86_64-w64-mingw32 - fi - # - mkdir -p $INSTALLPREFIX $INSTALLPREFIX/host/bin $DEPSDIR $BUILDDIR - # - # Need mingw-compiled openssl from bitcoin-deps: - cd $DEPSDIR - unzip $INDIR/bitcoin-deps-win${BITS}-gitian-r13.zip - # - cd $BUILDDIR - # - tar xzf $INDIR/qt-everywhere-opensource-src-5.2.0.tar.gz - cd qt-everywhere-opensource-src-5.2.0 - SPECNAME="win32-g++" - SPECFILE="qtbase/mkspecs/${SPECNAME}/qmake.conf" - sed 's/qt_instdate=`date +%Y-%m-%d`/qt_instdate=2011-01-30/' -i qtbase/configure - sed --posix "s|QMAKE_CFLAGS = -pipe -fno-keep-inline-dllexport|QMAKE_CFLAGS\t\t= -pipe -fno-keep-inline-dllexport -isystem /usr/$HOST/include/ -frandom-seed=qtbuild -I$DEPSDIR/include|" -i ${SPECFILE} - sed --posix "s|QMAKE_LFLAGS =|QMAKE_LFLAGS\t\t= -L$DEPSDIR/lib|" -i ${SPECFILE} - # Before we tried to pass arguments to ar (static linking) in using QMAKE_LIB, however - # qt removes the arguments for ar and provides a script which makes it impossible to pass the determinism flag - - # so rather than try to replace ar, post-process all libraries and plugins at the end. - # - # Don't load faketime while compiling Qt, qmake will get stuck in nearly infinite loops - #export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - #export FAKETIME=$REFERENCE_DATETIME - # - # Compile static libraries, and use statically linked openssl (-openssl-linked): - OPENSSL_LIBS="-L$DEPSDIR/lib -lssl -lcrypto -lgdi32" ./configure -prefix $INSTALLPREFIX -bindir $INSTALLPREFIX/host/bin -confirm-license -release -opensource -static -xplatform $SPECNAME -device-option CROSS_COMPILE="$HOST-" -no-audio-backend -no-javascript-jit -no-sql-sqlite -no-sql-odbc -no-nis -no-cups -no-iconv -no-dbus -no-gif -no-opengl -no-compile-examples -no-feature-style-windowsce -no-feature-style-windowsmobile -no-qml-debug -openssl-linked -skip qtsvg -skip qtwebkit -skip qtwebkit-examples -skip qtserialport -skip qtdeclarative -skip qtmultimedia -skip qtimageformats -skip qtlocation -skip qtsensors -skip qtquick1 -skip qtquickcontrols -skip qtactiveqt -skip qtconnectivity -skip qtwinextras -skip qtxmlpatterns -skip qtscript -skip qtdoc -system-libpng -system-zlib - make $MAKEOPTS install - # post-process all generated libraries and plugins to be deterministic - # extract them to a temporary directory then re-build them deterministically - for LIB in $(find $INSTALLPREFIX -name *.a); do - rm -rf $TEMPDIR && mkdir $TEMPDIR && cd $TEMPDIR - $HOST-ar xv $LIB | cut -b5- > /tmp/list.txt - rm $LIB - $HOST-ar crsD $LIB $(cat /tmp/list.txt) - done - # - cd $INSTALLPREFIX - # Remove unused non-deterministic stuff - rm host/bin/qtpaths.exe lib/libQt5Bootstrap.a lib/libQt5Bootstrap.la - # as zip stores file timestamps, use faketime to intercept stat calls to set dates for all files to reference date - export LD_PRELOAD=/usr/lib/faketime/libfaketime.so.1 - export FAKETIME=$REFERENCE_DATETIME - find -print0 | xargs -r0 touch # fix up timestamps before packaging - find | sort | zip -X@ $OUTDIR/qt-win${BITS}-5.2.0-gitian-r3.zip - unset LD_PRELOAD - unset FAKETIME - done # for BITS in diff --git a/depends/Makefile b/depends/Makefile index fc763bedeb..5de0159714 100644 --- a/depends/Makefile +++ b/depends/Makefile @@ -6,6 +6,7 @@ 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 d3c57956f1..e768feecf7 100644 --- a/depends/README.usage +++ b/depends/README.usage @@ -23,6 +23,7 @@ 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/bdb.mk b/depends/packages/bdb.mk index f39925723b..68841afdb8 100644 --- a/depends/packages/bdb.mk +++ b/depends/packages/bdb.mk @@ -8,8 +8,7 @@ $(package)_build_subdir=build_unix define $(package)_set_vars $(package)_config_opts=--disable-shared --enable-cxx --disable-replication $(package)_config_opts_mingw32=--enable-mingw -$(package)_config_opts_x86_64_linux=--with-pic -$(package)_config_opts_arm_linux=--with-pic +$(package)_config_opts_linux=--with-pic endef define $(package)_preprocess_cmds diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 53c4c3c74e..f50828c546 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -22,8 +22,7 @@ $(package)_toolset_darwin=darwin $(package)_archiver_darwin=$($(package)_libtool) $(package)_config_libraries=chrono,filesystem,program_options,system,thread,test $(package)_cxxflags=-fvisibility=hidden -$(package)_cxxflags_x86_64_linux=-fPIC -$(package)_cxxflags_arm_linux=-fPIC +$(package)_cxxflags_linux=-fPIC endef define $(package)_preprocess_cmds diff --git a/depends/packages/freetype.mk b/depends/packages/freetype.mk index b83cbd93ea..f7d6e0f9fc 100644 --- a/depends/packages/freetype.mk +++ b/depends/packages/freetype.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=c0848b29d52ef3ca27ad92e08351f023c5e24ce8cea7d8fe69fc96358 define $(package)_set_vars $(package)_config_opts=--without-zlib --without-png --disable-static - $(package)_config_opts_x86_64_linux=--with-pic + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds diff --git a/depends/packages/libICE.mk b/depends/packages/libICE.mk new file mode 100644 index 0000000000..fc60323b1c --- /dev/null +++ b/depends/packages/libICE.mk @@ -0,0 +1,23 @@ +package=libICE +$(package)_version=1.0.9 +$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ +$(package)_file_name=$(package)-$($(package)_version).tar.bz2 +$(package)_sha256_hash=8f7032f2c1c64352b5423f6b48a8ebdc339cc63064af34d66a6c9aa79759e202 +$(package)_dependencies=xtrans xproto + +define $(package)_set_vars + $(package)_config_opts=--disable-static --disable-docs --disable-specs --without-xsltproc + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/libSM.mk b/depends/packages/libSM.mk new file mode 100644 index 0000000000..0f9307ca76 --- /dev/null +++ b/depends/packages/libSM.mk @@ -0,0 +1,23 @@ +package=libSM +$(package)_version=1.2.2 +$(package)_download_path=http://xorg.freedesktop.org/releases/individual/lib/ +$(package)_file_name=$(package)-$($(package)_version).tar.bz2 +$(package)_sha256_hash=0baca8c9f5d934450a70896c4ad38d06475521255ca63b717a6510fdb6e287bd +$(package)_dependencies=xtrans xproto libICE + +define $(package)_set_vars + $(package)_config_opts=--without-libuuid --without-xsltproc --disable-docs --disable-static + $(package)_config_opts_linux=--with-pic +endef + +define $(package)_config_cmds + $($(package)_autoconf) +endef + +define $(package)_build_cmds + $(MAKE) +endef + +define $(package)_stage_cmds + $(MAKE) DESTDIR=$($(package)_staging_dir) install +endef diff --git a/depends/packages/libX11.mk b/depends/packages/libX11.mk index 144021e34b..178d592ee6 100644 --- a/depends/packages/libX11.mk +++ b/depends/packages/libX11.mk @@ -7,7 +7,7 @@ $(package)_dependencies=libxcb xtrans xextproto xproto define $(package)_set_vars $(package)_config_opts=--disable-xkb --disable-static -$(package)_config_opts_x86_64_linux=--with-pic +$(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds diff --git a/depends/packages/libXau.mk b/depends/packages/libXau.mk index 8c9b21846b..e87df2e4de 100644 --- a/depends/packages/libXau.mk +++ b/depends/packages/libXau.mk @@ -7,7 +7,7 @@ $(package)_dependencies=xproto define $(package)_set_vars $(package)_config_opts=--disable-shared - $(package)_config_opts_x86_64_linux=--with-pic + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds diff --git a/depends/packages/openssl.mk b/depends/packages/openssl.mk index 70b0b8d39f..6d7a556c11 100644 --- a/depends/packages/openssl.mk +++ b/depends/packages/openssl.mk @@ -10,12 +10,13 @@ $(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/o $(package)_config_opts+=no-krb5 no-camellia no-capieng no-cast no-cms no-dtls1 no-gost no-gmp no-heartbeats no-idea no-jpake no-md2 $(package)_config_opts+=no-mdc2 no-rc5 no-rdrand no-rfc3779 no-rsax no-sctp no-seed no-sha0 no-static_engine no-whirlpool no-rc2 no-rc4 no-ssl2 no-ssl3 $(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags) -$(package)_config_opts_x86_64_linux=-fPIC linux-x86_64 -$(package)_config_opts_arm_linux=-fPIC linux-generic32 +$(package)_config_opts_linux=-fPIC +$(package)_config_opts_x86_64_linux=linux-x86_64 +$(package)_config_opts_i686_linux=linux-generic32 +$(package)_config_opts_arm_linux=linux-generic32 $(package)_config_opts_x86_64_darwin=darwin64-x86_64-cc $(package)_config_opts_x86_64_mingw32=mingw64 $(package)_config_opts_i686_mingw32=mingw -$(package)_config_opts_i686_linux=linux-generic32 -fPIC endef define $(package)_preprocess_cmds diff --git a/depends/packages/packages.mk b/depends/packages/packages.mk index 0e1fbeffaa..305d21cb2d 100644 --- a/depends/packages/packages.mk +++ b/depends/packages/packages.mk @@ -2,8 +2,17 @@ packages:=boost openssl gmp native_packages := native_ccache native_comparisontool qt_native_packages = native_protobuf -qt_packages = qt qrencode protobuf -qt_linux_packages=expat dbus libxcb xcb_proto libXau xproto freetype fontconfig libX11 xextproto libXext xtrans +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_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/depends/packages/protobuf.mk b/depends/packages/protobuf.mk index 716f837853..5affad2837 100644 --- a/depends/packages/protobuf.mk +++ b/depends/packages/protobuf.mk @@ -7,7 +7,7 @@ $(package)_dependencies=native_$(package) define $(package)_set_vars $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc - $(package)_config_opts_x86_64_linux=--with-pic + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds diff --git a/depends/packages/qrencode.mk b/depends/packages/qrencode.mk index 69d2982cbc..1ad329e94d 100644 --- a/depends/packages/qrencode.mk +++ b/depends/packages/qrencode.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=dfd71487513c871bad485806bfd1fdb304dedc84d2b01a8fb8e0940b5 define $(package)_set_vars $(package)_config_opts=--disable-shared -without-tools --disable-sdltest -$(package)_config_opts_x86_64_linux=--with-pic +$(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds diff --git a/depends/packages/qt46.mk b/depends/packages/qt46.mk new file mode 100644 index 0000000000..8fb30a5c44 --- /dev/null +++ b/depends/packages/qt46.mk @@ -0,0 +1,66 @@ +PACKAGE=qt46 +$(package)_version=4.6.4 +$(package)_download_path=http://download.qt-project.org/archive/qt/4.6/ +$(package)_file_name=qt-everywhere-opensource-src-$($(package)_version).tar.gz +$(package)_sha256_hash=9ad4d46c721b53a429ed5a2eecfd3c239a9ab566562f183f99d3125f1a234250 +$(package)_dependencies=openssl freetype dbus libX11 xproto libXext libICE libSM +$(package)_patches=stlfix.patch + +define $(package)_set_vars +$(package)_config_opts = -prefix $(host_prefix) -headerdir $(host_prefix)/include/qt4 -bindir $(build_prefix)/bin +$(package)_config_opts += -release -no-separate-debug-info -opensource -confirm-license +$(package)_config_opts += -stl -qt-zlib + +$(package)_config_opts += -nomake examples -nomake tests -nomake tools -nomake translations -nomake demos -nomake docs +$(package)_config_opts += -no-audio-backend -no-glib -no-nis -no-cups -no-iconv -no-gif -no-pch +$(package)_config_opts += -no-xkb -no-xrender -no-xrandr -no-xfixes -no-xcursor -no-xinerama -no-xsync -no-xinput -no-mitshm -no-xshape +$(package)_config_opts += -no-libtiff -no-fontconfig -openssl-linked +$(package)_config_opts += -no-sql-db2 -no-sql-ibase -no-sql-oci -no-sql-tds -no-sql-mysql +$(package)_config_opts += -no-sql-odbc -no-sql-psql -no-sql-sqlite -no-sql-sqlite2 +$(package)_config_opts += -no-xmlpatterns -no-multimedia -no-phonon -no-scripttools -no-declarative +$(package)_config_opts += -no-phonon-backend -no-webkit -no-javascript-jit -no-script +$(package)_config_opts += -no-svg -no-libjpeg -no-libtiff -no-libpng -no-libmng -no-qt3support -no-opengl + +$(package)_config_opts_x86_64_linux += -platform linux-g++-64 +$(package)_config_opts_i686_linux = -platform linux-g++-32 +$(package)_build_env = QT_RCC_TEST=1 +endef + +define $(package)_preprocess_cmds + sed -i.old "s|/include /usr/include||" config.tests/unix/freetype/freetype.pri && \ + sed -i.old "s|src_plugins.depends = src_gui src_sql src_svg|src_plugins.depends = src_gui src_sql|" src/src.pro && \ + sed -i.old "s|\.lower(|\.toLower(|g" src/network/ssl/qsslsocket_openssl.cpp && \ + sed -i.old "s|Key_BackSpace|Key_Backspace|" src/gui/itemviews/qabstractitemview.cpp && \ + sed -i.old "s|/usr/X11R6/lib64|$(host_prefix)/lib|" mkspecs/*/*.conf && \ + sed -i.old "s|/usr/X11R6/lib|$(host_prefix)/lib|" mkspecs/*/*.conf && \ + sed -i.old "s|/usr/X11R6/include|$(host_prefix)/include|" mkspecs/*/*.conf && \ + sed -i.old "s|QMAKE_LFLAGS_SHLIB\t+= -shared|QMAKE_LFLAGS_SHLIB\t+= -shared -Wl,--exclude-libs,ALL|" mkspecs/common/g++.conf && \ + sed -i.old "/SSLv2_client_method/d" src/network/ssl/qsslsocket_openssl.cpp src/network/ssl/qsslsocket_openssl_symbols.cpp && \ + sed -i.old "/SSLv2_server_method/d" src/network/ssl/qsslsocket_openssl.cpp src/network/ssl/qsslsocket_openssl_symbols.cpp && \ + patch -p1 < $($(package)_patch_dir)/stlfix.patch +endef + +define $(package)_config_cmds + export PKG_CONFIG_SYSROOT_DIR=/ && \ + export PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig && \ + export PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig && \ + export CPATH=$(host_prefix)/include && \ + OPENSSL_LIBS='-L$(host_prefix)/lib -lssl -lcrypto' ./configure $($(package)_config_opts) && \ + cd tools/linguist/lrelease; ../../../bin/qmake -o Makefile lrelease.pro +endef + +define $(package)_build_cmds + export CPATH=$(host_prefix)/include && \ + $(MAKE) -C src && \ + $(MAKE) -C tools/linguist/lrelease +endef + +define $(package)_stage_cmds + $(MAKE) -C src INSTALL_ROOT=$($(package)_staging_dir) install && \ + $(MAKE) -C tools/linguist/lrelease INSTALL_ROOT=$($(package)_staging_dir) install +endef + +define $(package)_postprocess_cmds + rm -rf mkspecs/ lib/cmake/ lib/*.prl lib/*.la && \ + find native/bin -type f -exec mv {} {}-qt4 \; +endef diff --git a/depends/packages/xcb_proto.mk b/depends/packages/xcb_proto.mk index 726e3048c3..0c7c958d62 100644 --- a/depends/packages/xcb_proto.mk +++ b/depends/packages/xcb_proto.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=7ef40ddd855b750bc597d2a435da21e55e502a0fefa85b274f2c92280 define $(package)_set_vars $(package)_config_opts=--disable-shared - $(package)_config_opts_x86_64_linux=--with-pic + $(package)_config_opts_linux=--with-pic endef define $(package)_config_cmds diff --git a/depends/packages/xtrans.mk b/depends/packages/xtrans.mk index b973149797..99eefa6d5e 100644 --- a/depends/packages/xtrans.mk +++ b/depends/packages/xtrans.mk @@ -6,7 +6,7 @@ $(package)_sha256_hash=054d4ee3efd52508c753e9f7bc655ef185a29bd2850dd9e2fc2ccc335 $(package)_dependencies= define $(package)_set_vars -$(package)_config_opts_x86_64_linux=--with-pic --disable-static +$(package)_config_opts_linux=--with-pic --disable-static endef define $(package)_config_cmds diff --git a/depends/patches/qt46/stlfix.patch b/depends/patches/qt46/stlfix.patch new file mode 100644 index 0000000000..f8f6fb04b0 --- /dev/null +++ b/depends/patches/qt46/stlfix.patch @@ -0,0 +1,10 @@ +--- old/config.tests/unix/stl/stltest.cpp 2011-06-23 03:45:23.000000000 -0400 ++++ new/config.tests/unix/stl/stltest.cpp 2014-08-28 00:54:04.154837604 -0400 +@@ -49,6 +49,7 @@ + #include <vector> + #include <algorithm> + #include <iostream> ++#include <cstddef> + + // something mean to see if the compiler and C++ standard lib are good enough + template<class K, class T> diff --git a/doc/coding.md b/doc/coding.md index b9d2006e3c..43294dbe4c 100644 --- a/doc/coding.md +++ b/doc/coding.md @@ -115,8 +115,6 @@ Threads - StartNode : Starts other threads. -- ThreadGetMyExternalIP : Determines outside-the-firewall IP address, sends addr message to connected peers when it determines it. - - ThreadDNSAddressSeed : Loads addresses of peers from the DNS. - ThreadMapPort : Universal plug-and-play startup/shutdown diff --git a/doc/release-process.md b/doc/release-process.md index 7699af90bd..c6a7266ef1 100644 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -23,6 +23,10 @@ Release Process * * * +###update gitian + + In order to take advantage of the new caching features in gitian, be sure to update to a recent version (e9741525c or higher is recommended) + ###perform gitian builds From a directory containing the bitcoin source, gitian-builder and gitian.sigs @@ -46,71 +50,6 @@ Release Process tar -C /Volumes/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/ -czf MacOSX10.7.sdk.tar.gz MacOSX10.7.sdk - Download remaining inputs, and build everything: - - wget 'http://miniupnp.free.fr/files/download.php?file=miniupnpc-1.9.tar.gz' -O miniupnpc-1.9.tar.gz - wget 'https://www.openssl.org/source/openssl-1.0.1h.tar.gz' - wget 'http://download.oracle.com/berkeley-db/db-4.8.30.NC.tar.gz' - wget 'http://zlib.net/zlib-1.2.8.tar.gz' - wget 'ftp://ftp.simplesystems.org/pub/png/src/history/libpng16/libpng-1.6.8.tar.gz' - wget 'https://fukuchi.org/works/qrencode/qrencode-3.4.3.tar.bz2' - wget 'https://downloads.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.bz2' - wget 'https://svn.boost.org/trac/boost/raw-attachment/ticket/7262/boost-mingw.patch' -O boost-mingw-gas-cross-compile-2013-03-03.patch - wget 'https://download.qt-project.org/official_releases/qt/5.2/5.2.0/single/qt-everywhere-opensource-src-5.2.0.tar.gz' - wget 'https://download.qt-project.org/official_releases/qt/5.2/5.2.1/single/qt-everywhere-opensource-src-5.2.1.tar.gz' - wget 'https://download.qt-project.org/archive/qt/4.6/qt-everywhere-opensource-src-4.6.4.tar.gz' - wget 'https://protobuf.googlecode.com/files/protobuf-2.5.0.tar.bz2' - wget 'https://github.com/mingwandroid/toolchain4/archive/10cc648683617cca8bcbeae507888099b41b530c.tar.gz' - wget 'http://www.opensource.apple.com/tarballs/cctools/cctools-809.tar.gz' - wget 'http://www.opensource.apple.com/tarballs/dyld/dyld-195.5.tar.gz' - wget 'http://www.opensource.apple.com/tarballs/ld64/ld64-127.2.tar.gz' - wget 'http://pkgs.fedoraproject.org/repo/pkgs/cdrkit/cdrkit-1.1.11.tar.gz/efe08e2f3ca478486037b053acd512e9/cdrkit-1.1.11.tar.gz' - wget 'https://github.com/theuni/libdmg-hfsplus/archive/libdmg-hfsplus-v0.1.tar.gz' - wget 'http://llvm.org/releases/3.2/clang+llvm-3.2-x86-linux-ubuntu-12.04.tar.gz' -O clang-llvm-3.2-x86-linux-ubuntu-12.04.tar.gz - wget 'https://raw.githubusercontent.com/theuni/osx-cross-depends/master/patches/cdrtools/genisoimage.diff' -O cdrkit-deterministic.patch - cd .. - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-linux.yml - mv build/out/boost-*.zip inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/deps-linux.yml - mv build/out/bitcoin-deps-*.zip inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/qt-linux.yml - mv build/out/qt-*.tar.gz inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/boost-win.yml - mv build/out/boost-*.zip inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/deps-win.yml - mv build/out/bitcoin-deps-*.zip inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/qt-win.yml - mv build/out/qt-*.zip inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/protobuf-win.yml - mv build/out/protobuf-*.zip inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/gitian-osx-native.yml - mv build/out/osx-*.tar.gz inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/gitian-osx-depends.yml - mv build/out/osx-*.tar.gz inputs/ - ./bin/gbuild ../bitcoin/contrib/gitian-descriptors/gitian-osx-qt.yml - mv build/out/osx-*.tar.gz inputs/ - - The expected SHA256 hashes of the intermediate inputs are: - - f29b7d9577417333fb56e023c2977f5726a7c297f320b175a4108cf7cd4c2d29 boost-linux32-1.55.0-gitian-r1.zip - 88232451c4104f7eb16e469ac6474fd1231bd485687253f7b2bdf46c0781d535 boost-linux64-1.55.0-gitian-r1.zip - 46710f673467e367738d8806e45b4cb5931aaeea61f4b6b55a68eea56d5006c5 bitcoin-deps-linux32-gitian-r6.zip - f03be39fb26670243d3a659e64d18e19d03dec5c11e9912011107768390b5268 bitcoin-deps-linux64-gitian-r6.zip - 57e57dbdadc818cd270e7e00500a5e1085b3bcbdef69a885f0fb7573a8d987e1 qt-linux32-4.6.4-gitian-r1.tar.gz - 60eb4b9c5779580b7d66529efa5b2836ba1a70edde2a0f3f696d647906a826be qt-linux64-4.6.4-gitian-r1.tar.gz - 60dc2d3b61e9c7d5dbe2f90d5955772ad748a47918ff2d8b74e8db9b1b91c909 boost-win32-1.55.0-gitian-r6.zip - f65fcaf346bc7b73bc8db3a8614f4f6bee2f61fcbe495e9881133a7c2612a167 boost-win64-1.55.0-gitian-r6.zip - 70de248cd0dd7e7476194129e818402e974ca9c5751cbf591644dc9f332d3b59 bitcoin-deps-win32-gitian-r13.zip - 9eace4c76f639f4f3580a478eee4f50246e1bbb5ccdcf37a158261a5a3fa3e65 bitcoin-deps-win64-gitian-r13.zip - 963e3e5e85879010a91143c90a711a5d1d5aba992e38672cdf7b54e42c56b2f1 qt-win32-5.2.0-gitian-r3.zip - 751c579830d173ef3e6f194e83d18b92ebef6df03289db13ab77a52b6bc86ef0 qt-win64-5.2.0-gitian-r3.zip - e2e403e1a08869c7eed4d4293bce13d51ec6a63592918b90ae215a0eceb44cb4 protobuf-win32-2.5.0-gitian-r4.zip - a0999037e8b0ef9ade13efd88fee261ba401f5ca910068b7e0cd3262ba667db0 protobuf-win64-2.5.0-gitian-r4.zip - 512bc0622c883e2e0f4cbc3fedfd8c2402d06c004ce6fb32303cc2a6f405b6df osx-native-depends-r3.tar.gz - 927e4b222be6d590b4bc2fc185872a5d0ca5c322adb983764d3ed84be6bdbc81 osx-depends-r4.tar.gz - ec95abef1df2b096a970359787c01d8c45e2a4475b7ae34e12c022634fbdba8a osx-depends-qt-5.2.1-r4.tar.gz - - Build Bitcoin Core for Linux, Windows, and OS X: ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-linux.yml @@ -125,8 +64,8 @@ Release Process zip -r bitcoin-${VERSION}-win-gitian.zip * mv bitcoin-${VERSION}-win-gitian.zip ../../../ popd - ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx-bitcoin.yml - ./bin/gsign --signer $SIGNER --release ${VERSION}-osx --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx-bitcoin.yml + ./bin/gbuild --commit bitcoin=v${VERSION} ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml + ./bin/gsign --signer $SIGNER --release ${VERSION}-osx --destination ../gitian.sigs/ ../bitcoin/contrib/gitian-descriptors/gitian-osx.yml pushd build/out mv Bitcoin-Qt.dmg ../../../ popd diff --git a/qa/pull-tester/rpc-tests.sh b/qa/pull-tester/rpc-tests.sh index 0b5ad20642..e01e870390 100755 --- a/qa/pull-tester/rpc-tests.sh +++ b/qa/pull-tester/rpc-tests.sh @@ -16,8 +16,10 @@ fi #Run the tests if [ "x${ENABLE_BITCOIND}${ENABLE_UTILS}${ENABLE_WALLET}" = "x111" ]; then - ${BUILDDIR}/qa/rpc-tests/wallet.sh "${BUILDDIR}/src" + ${BUILDDIR}/qa/rpc-tests/wallet.py --srcdir "${BUILDDIR}/src" ${BUILDDIR}/qa/rpc-tests/listtransactions.py --srcdir "${BUILDDIR}/src" + ${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --srcdir "${BUILDDIR}/src" + ${BUILDDIR}/qa/rpc-tests/txn_doublespend.py --mineblock --srcdir "${BUILDDIR}/src" #${BUILDDIR}/qa/rpc-tests/forknotify.py --srcdir "${BUILDDIR}/src" else echo "No rpc tests to run. Wallet, utils, and bitcoind must all be enabled" diff --git a/qa/rpc-tests/getblocktemplate.py b/qa/rpc-tests/getblocktemplate_longpoll.py index 500662bf87..263a5f6d59 100755 --- a/qa/rpc-tests/getblocktemplate.py +++ b/qa/rpc-tests/getblocktemplate_longpoll.py @@ -3,8 +3,6 @@ # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -# Exercise the listtransactions API - from test_framework import BitcoinTestFramework from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException from util import * @@ -46,7 +44,7 @@ class LongpollThread(threading.Thread): def run(self): self.node.getblocktemplate({'longpollid':self.longpollid}) -class GetBlockTemplateTest(BitcoinTestFramework): +class GetBlockTemplateLPTest(BitcoinTestFramework): ''' Test longpolling with getblocktemplate. ''' @@ -90,5 +88,5 @@ class GetBlockTemplateTest(BitcoinTestFramework): assert(not thr.is_alive()) if __name__ == '__main__': - GetBlockTemplateTest().main() + GetBlockTemplateLPTest().main() diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/qa/rpc-tests/getblocktemplate_proposals.py new file mode 100755 index 0000000000..0f7859584a --- /dev/null +++ b/qa/rpc-tests/getblocktemplate_proposals.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python +# Copyright (c) 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. + +from test_framework import BitcoinTestFramework +from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException +from util import * + +from binascii import a2b_hex, b2a_hex +from hashlib import sha256 +from struct import pack + + +def check_array_result(object_array, to_match, expected): + """ + Pass in array of JSON objects, a dictionary with key/value pairs + to match against, and another dictionary with expected key/value + pairs. + """ + num_matched = 0 + for item in object_array: + all_match = True + for key,value in to_match.items(): + if item[key] != value: + all_match = False + if not all_match: + continue + for key,value in expected.items(): + if item[key] != value: + raise AssertionError("%s : expected %s=%s"%(str(item), str(key), str(value))) + num_matched = num_matched+1 + if num_matched == 0: + raise AssertionError("No objects matched %s"%(str(to_match))) + +def b2x(b): + return b2a_hex(b).decode('ascii') + +# NOTE: This does not work for signed numbers (set the high bit) or zero (use b'\0') +def encodeUNum(n): + s = bytearray(b'\1') + while n > 127: + s[0] += 1 + s.append(n % 256) + n //= 256 + s.append(n) + return bytes(s) + +def varlenEncode(n): + if n < 0xfd: + return pack('<B', n) + if n <= 0xffff: + return b'\xfd' + pack('<H', n) + if n <= 0xffffffff: + return b'\xfe' + pack('<L', n) + return b'\xff' + pack('<Q', n) + +def dblsha(b): + return sha256(sha256(b).digest()).digest() + +def genmrklroot(leaflist): + cur = leaflist + while len(cur) > 1: + n = [] + if len(cur) & 1: + cur.append(cur[-1]) + for i in range(0, len(cur), 2): + n.append(dblsha(cur[i] + cur[i+1])) + cur = n + return cur[0] + +def template_to_bytes(tmpl, txlist): + blkver = pack('<L', tmpl['version']) + mrklroot = genmrklroot(list(dblsha(a) for a in txlist)) + timestamp = pack('<L', tmpl['curtime']) + nonce = b'\0\0\0\0' + blk = blkver + a2b_hex(tmpl['previousblockhash'])[::-1] + mrklroot + timestamp + a2b_hex(tmpl['bits'])[::-1] + nonce + blk += varlenEncode(len(txlist)) + for tx in txlist: + blk += tx + return blk + +def template_to_hex(tmpl, txlist): + return b2x(template_to_bytes(tmpl, txlist)) + +def assert_template(node, tmpl, txlist, expect): + rsp = node.getblocktemplate({'data':template_to_hex(tmpl, txlist),'mode':'proposal'}) + if rsp != expect: + raise AssertionError('unexpected: %s' % (rsp,)) + +class GetBlockTemplateProposalTest(BitcoinTestFramework): + ''' + Test block proposals with getblocktemplate. + ''' + + def run_test(self): + node = self.nodes[0] + tmpl = node.getblocktemplate() + if 'coinbasetxn' not in tmpl: + rawcoinbase = encodeUNum(tmpl['height']) + rawcoinbase += b'\x01-' + hexcoinbase = b2x(rawcoinbase) + hexoutval = b2x(pack('<Q', tmpl['coinbasevalue'])) + tmpl['coinbasetxn'] = {'data': '01000000' + '01' + '0000000000000000000000000000000000000000000000000000000000000000ffffffff' + ('%02x' % (len(rawcoinbase),)) + hexcoinbase + 'fffffffe' + '01' + hexoutval + '00' + '00000000'} + txlist = list(bytearray(a2b_hex(a['data'])) for a in (tmpl['coinbasetxn'],) + tuple(tmpl['transactions'])) + + # Test 0: Capability advertised + assert('proposal' in tmpl['capabilities']) + + # NOTE: This test currently FAILS (regtest mode doesn't enforce block height in coinbase) + ## Test 1: Bad height in coinbase + #txlist[0][4+1+36+1+1] += 1 + #assert_template(node, tmpl, txlist, 'FIXME') + #txlist[0][4+1+36+1+1] -= 1 + + # Test 2: Bad input hash for gen tx + txlist[0][4+1] += 1 + assert_template(node, tmpl, txlist, 'bad-cb-missing') + txlist[0][4+1] -= 1 + + # Test 3: Truncated final tx + lastbyte = txlist[-1].pop() + try: + assert_template(node, tmpl, txlist, 'n/a') + except JSONRPCException: + pass # Expected + txlist[-1].append(lastbyte) + + # Test 4: Add an invalid tx to the end (duplicate of gen tx) + txlist.append(txlist[0]) + assert_template(node, tmpl, txlist, 'bad-txns-duplicate') + txlist.pop() + + # Test 5: Add an invalid tx to the end (non-duplicate) + txlist.append(bytearray(txlist[0])) + txlist[-1][4+1] = b'\xff' + assert_template(node, tmpl, txlist, 'bad-txns-inputs-missingorspent') + txlist.pop() + + # Test 6: Future tx lock time + txlist[0][-4:] = b'\xff\xff\xff\xff' + assert_template(node, tmpl, txlist, 'bad-txns-nonfinal') + txlist[0][-4:] = b'\0\0\0\0' + + # Test 7: Bad tx count + txlist.append(b'') + try: + assert_template(node, tmpl, txlist, 'n/a') + except JSONRPCException: + pass # Expected + txlist.pop() + + # Test 8: Bad bits + realbits = tmpl['bits'] + tmpl['bits'] = '1c0000ff' # impossible in the real world + assert_template(node, tmpl, txlist, 'bad-diffbits') + tmpl['bits'] = realbits + + # Test 9: Bad merkle root + rawtmpl = template_to_bytes(tmpl, txlist) + rawtmpl[4+32] = (rawtmpl[4+32] + 1) % 0x100 + rsp = node.getblocktemplate({'data':b2x(rawtmpl),'mode':'proposal'}) + if rsp != 'bad-txnmrklroot': + raise AssertionError('unexpected: %s' % (rsp,)) + + # Test 10: Bad timestamps + realtime = tmpl['curtime'] + tmpl['curtime'] = 0x7fffffff + assert_template(node, tmpl, txlist, 'time-too-new') + tmpl['curtime'] = 0 + assert_template(node, tmpl, txlist, 'time-too-old') + tmpl['curtime'] = realtime + + # Test 11: Valid block + assert_template(node, tmpl, txlist, None) + + # Test 12: Orphan block + tmpl['previousblockhash'] = 'ff00' * 16 + assert_template(node, tmpl, txlist, 'inconclusive-not-best-prevblk') + +if __name__ == '__main__': + GetBlockTemplateProposalTest().main() diff --git a/qa/rpc-tests/txn_doublespend.py b/qa/rpc-tests/txn_doublespend.py new file mode 100755 index 0000000000..6125147ebc --- /dev/null +++ b/qa/rpc-tests/txn_doublespend.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +# Copyright (c) 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. + +# +# Test proper accounting with malleable transactions +# + +from test_framework import BitcoinTestFramework +from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException +from decimal import Decimal +from util import * +import os +import shutil + +class TxnMallTest(BitcoinTestFramework): + + def add_options(self, parser): + parser.add_option("--mineblock", dest="mine_block", default=False, action="store_true", + help="Test double-spend of 1-confirmed transaction") + + def setup_network(self): + # Start with split network: + return super(TxnMallTest, self).setup_network(True) + + def run_test(self): + # All nodes should start with 1,250 BTC: + starting_balance = 1250 + for i in range(4): + assert_equal(self.nodes[i].getbalance(), starting_balance) + self.nodes[i].getnewaddress("") # bug workaround, coins generated assigned to first getnewaddress! + + # Assign coins to foo and bar accounts: + self.nodes[0].move("", "foo", 1220) + self.nodes[0].move("", "bar", 30) + assert_equal(self.nodes[0].getbalance(""), 0) + + # Coins are sent to node1_address + node1_address = self.nodes[1].getnewaddress("from0") + + # First: use raw transaction API to send 1210 BTC to node1_address, + # but don't broadcast: + (total_in, inputs) = gather_inputs(self.nodes[0], 1210) + change_address = self.nodes[0].getnewaddress("foo") + outputs = {} + outputs[change_address] = 40 + outputs[node1_address] = 1210 + rawtx = self.nodes[0].createrawtransaction(inputs, outputs) + doublespend = self.nodes[0].signrawtransaction(rawtx) + assert_equal(doublespend["complete"], True) + + # Create two transaction from node[0] to node[1]; the + # second must spend change from the first because the first + # spends all mature inputs: + txid1 = self.nodes[0].sendfrom("foo", node1_address, 1210, 0) + txid2 = self.nodes[0].sendfrom("bar", node1_address, 20, 0) + + # Have node0 mine a block: + if (self.options.mine_block): + self.nodes[0].setgenerate(True, 1) + sync_blocks(self.nodes[0:2]) + + tx1 = self.nodes[0].gettransaction(txid1) + tx2 = self.nodes[0].gettransaction(txid2) + + # Node0's balance should be starting balance, plus 50BTC for another + # matured block, minus 1210, minus 20, and minus transaction fees: + expected = starting_balance + if self.options.mine_block: expected += 50 + expected += tx1["amount"] + tx1["fee"] + expected += tx2["amount"] + tx2["fee"] + assert_equal(self.nodes[0].getbalance(), expected) + + # foo and bar accounts should be debited: + assert_equal(self.nodes[0].getbalance("foo"), 1220+tx1["amount"]+tx1["fee"]) + assert_equal(self.nodes[0].getbalance("bar"), 30+tx2["amount"]+tx2["fee"]) + + if self.options.mine_block: + assert_equal(tx1["confirmations"], 1) + assert_equal(tx2["confirmations"], 1) + # Node1's "from0" balance should be both transaction amounts: + assert_equal(self.nodes[1].getbalance("from0"), -(tx1["amount"]+tx2["amount"])) + else: + assert_equal(tx1["confirmations"], 0) + assert_equal(tx2["confirmations"], 0) + + # Now give doublespend to miner: + mutated_txid = self.nodes[2].sendrawtransaction(doublespend["hex"]) + # ... mine a block... + self.nodes[2].setgenerate(True, 1) + + # Reconnect the split network, and sync chain: + connect_nodes(self.nodes[1], 2) + self.nodes[2].setgenerate(True, 1) # Mine another block to make sure we sync + sync_blocks(self.nodes) + + # Re-fetch transaction info: + tx1 = self.nodes[0].gettransaction(txid1) + tx2 = self.nodes[0].gettransaction(txid2) + + # Both transactions should be conflicted + assert_equal(tx1["confirmations"], -1) + assert_equal(tx2["confirmations"], -1) + + # Node0's total balance should be starting balance, plus 100BTC for + # two more matured blocks, minus 1210 for the double-spend: + expected = starting_balance + 100 - 1210 + assert_equal(self.nodes[0].getbalance(), expected) + assert_equal(self.nodes[0].getbalance("*"), expected) + + # foo account should be debited, but bar account should not: + assert_equal(self.nodes[0].getbalance("foo"), 1220-1210) + assert_equal(self.nodes[0].getbalance("bar"), 30) + + # Node1's "from" account balance should be just the mutated send: + assert_equal(self.nodes[1].getbalance("from0"), 1210) + +if __name__ == '__main__': + TxnMallTest().main() diff --git a/qa/rpc-tests/txnmall.sh b/qa/rpc-tests/txnmall.sh deleted file mode 100755 index 1296d54d92..0000000000 --- a/qa/rpc-tests/txnmall.sh +++ /dev/null @@ -1,152 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 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. - -# Test proper accounting with malleable transactions - -if [ $# -lt 1 ]; then - echo "Usage: $0 path_to_binaries" - echo "e.g. $0 ../../src" - echo "Env vars BITCOIND and BITCOINCLI may be used to specify the exact binaries used" - exit 1 -fi - -set -f - -BITCOIND=${BITCOIND:-${1}/bitcoind} -CLI=${BITCOINCLI:-${1}/bitcoin-cli} - -DIR="${BASH_SOURCE%/*}" -SENDANDWAIT="${DIR}/send.sh" -if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi -. "$DIR/util.sh" - -D=$(mktemp -d test.XXXXX) - -# Two nodes; one will play the part of merchant, the -# other an evil transaction-mutating miner. - -D1=${D}/node1 -CreateDataDir $D1 port=11000 rpcport=11001 -B1ARGS="-datadir=$D1" -$BITCOIND $B1ARGS & -B1PID=$! - -D2=${D}/node2 -CreateDataDir $D2 port=11010 rpcport=11011 -B2ARGS="-datadir=$D2" -$BITCOIND $B2ARGS & -B2PID=$! - -# Wait until both nodes are at the same block number -function WaitBlocks { - while : - do - sleep 1 - declare -i BLOCKS1=$( GetBlocks $B1ARGS ) - declare -i BLOCKS2=$( GetBlocks $B2ARGS ) - if (( BLOCKS1 == BLOCKS2 )) - then - break - fi - done -} - -# Wait until node has $N peers -function WaitPeers { - while : - do - declare -i PEERS=$( $CLI $1 getconnectioncount ) - if (( PEERS == "$2" )) - then - break - fi - sleep 1 - done -} - -echo "Generating test blockchain..." - -# Start with B2 connected to B1: -$CLI $B2ARGS addnode 127.0.0.1:11000 onetry -WaitPeers "$B1ARGS" 1 - -# 1 block, 50 XBT each == 50 XBT -$CLI $B1ARGS setgenerate true 1 - -WaitBlocks -# 100 blocks, 0 mature == 0 XBT -$CLI $B2ARGS setgenerate true 100 -WaitBlocks - -CheckBalance "$B1ARGS" 50 -CheckBalance "$B2ARGS" 0 - -# restart B2 with no connection -$CLI $B2ARGS stop > /dev/null 2>&1 -wait $B2PID -$BITCOIND $B2ARGS & -B2PID=$! - -B2ADDRESS=$( $CLI $B2ARGS getaccountaddress "from1" ) - -# Have B1 create two transactions; second will -# spend change from first, since B1 starts with only a single -# 50 bitcoin output: -$CLI $B1ARGS move "" "foo" 10.0 > /dev/null -$CLI $B1ARGS move "" "bar" 10.0 > /dev/null -TXID1=$( $CLI $B1ARGS sendfrom foo $B2ADDRESS 1.0 0) -TXID2=$( $CLI $B1ARGS sendfrom bar $B2ADDRESS 2.0 0) - -# Mutate TXID1 and add it to B2's memory pool: -RAWTX1=$( $CLI $B1ARGS getrawtransaction $TXID1 ) -# RAWTX1 is hex-encoded, serialized transaction. So each -# byte is two characters; we'll prepend the first -# "push" in the scriptsig with OP_PUSHDATA1 (0x4c), -# and add one to the length of the signature. -# Fields are fixed; from the beginning: -# 4-byte version -# 1-byte varint number-of inputs (one in this case) -# 32-byte previous txid -# 4-byte previous output -# 1-byte varint length-of-scriptsig -# 1-byte PUSH this many bytes onto stack -# ... etc -# So: to mutate, we want to get byte 41 (hex characters 82-83), -# increment it, and insert 0x4c after it. -L=${RAWTX1:82:2} -NEWLEN=$( printf "%x" $(( 16#$L + 1 )) ) -MUTATEDTX1=${RAWTX1:0:82}${NEWLEN}4c${RAWTX1:84} -# ... give mutated tx1 to B2: -MUTATEDTXID=$( $CLI $B2ARGS sendrawtransaction $MUTATEDTX1 ) - -echo "TXID1: " $TXID1 -echo "Mutated: " $MUTATEDTXID - -# Re-connect nodes, and have B2 mine a block -# containing the mutant: -$CLI $B2ARGS addnode 127.0.0.1:11000 onetry -$CLI $B2ARGS setgenerate true 1 -WaitBlocks - -# B1 should have 49 BTC; the 2 BTC send is -# conflicted, and should not count in -# balances. -CheckBalance "$B1ARGS" 49 -CheckBalance "$B1ARGS" 49 "*" -CheckBalance "$B1ARGS" 9 "foo" -CheckBalance "$B1ARGS" 10 "bar" - -# B2 should have 51 BTC -CheckBalance "$B2ARGS" 51 -CheckBalance "$B2ARGS" 1 "from1" - -$CLI $B2ARGS stop > /dev/null 2>&1 -wait $B2PID -$CLI $B1ARGS stop > /dev/null 2>&1 -wait $B1PID - -echo "Tests successful, cleaning up" -rm -rf $D -exit 0 diff --git a/qa/rpc-tests/util.py b/qa/rpc-tests/util.py index c6d918a81c..bed7fed8ca 100644 --- a/qa/rpc-tests/util.py +++ b/qa/rpc-tests/util.py @@ -57,7 +57,6 @@ def sync_mempools(rpc_connections): if num_match == len(rpc_connections): break time.sleep(1) - bitcoind_processes = {} @@ -130,6 +129,15 @@ def initialize_chain(test_dir): shutil.copytree(from_dir, to_dir) initialize_datadir(test_dir, i) # Overwrite port/rpcport in bitcoin.conf +def initialize_chain_clean(test_dir, num_nodes): + """ + Create an empty blockchain and num_nodes wallets. + Useful if a test case wants complete control over initialization. + """ + for i in range(num_nodes): + datadir=initialize_datadir(test_dir, i) + + def _rpchost_to_args(rpchost): '''Convert optional IP:port spec to rpcconnect/rpcport args''' if rpchost is None: @@ -221,11 +229,13 @@ def find_output(node, txid, amount): return i raise RuntimeError("find_output txid %s : %s not found"%(txid,str(amount))) -def gather_inputs(from_node, amount_needed): + +def gather_inputs(from_node, amount_needed, confirmations_required=1): """ Return a random set of unspent txouts that are enough to pay amount_needed """ - utxo = from_node.listunspent(1) + assert(confirmations_required >=0) + utxo = from_node.listunspent(confirmations_required) random.shuffle(utxo) inputs = [] total_in = Decimal("0.00000000") diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py new file mode 100755 index 0000000000..4271d96be7 --- /dev/null +++ b/qa/rpc-tests/wallet.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python +# Copyright (c) 2014 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. + +# +# Exercise the wallet. Ported from wallet.sh. +# Does the following: +# a) creates 3 nodes, with an empty chain (no blocks). +# b) node0 mines a block +# c) node1 mines 101 blocks, so now nodes 0 and 1 have 50btc, node2 has none. +# d) node0 sends 21 btc to node2, in two transactions (11 btc, then 10 btc). +# e) node0 mines a block, collects the fee on the second transaction +# f) node1 mines 100 blocks, to mature node0's just-mined block +# g) check that node0 has 100-21, node2 has 21 +# h) node0 should now have 2 unspent outputs; send these to node2 via raw tx broadcast by node1 +# i) have node1 mine a block +# j) check balances - node0 should have 0, node2 should have 100 +# + +from test_framework import BitcoinTestFramework +from util import * + + +class WalletTest (BitcoinTestFramework): + + def setup_chain(self): + print("Initializing test directory "+self.options.tmpdir) + initialize_chain_clean(self.options.tmpdir, 3) + + def setup_network(self, split=False): + self.nodes = start_nodes(3, self.options.tmpdir) + connect_nodes_bi(self.nodes,0,1) + connect_nodes_bi(self.nodes,1,2) + connect_nodes_bi(self.nodes,0,2) + self.is_network_split=False + self.sync_all() + + def run_test (self): + print "Mining blocks..." + + self.nodes[0].setgenerate(True, 1) + + self.sync_all() + self.nodes[1].setgenerate(True, 101) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 50) + assert_equal(self.nodes[1].getbalance(), 50) + assert_equal(self.nodes[2].getbalance(), 0) + + # Send 21 BTC from 0 to 2 using sendtoaddress call. + # Second transaction will be child of first, and will require a fee + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 11) + self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 10) + + # Have node0 mine a block, thus he will collect his own fee. + self.nodes[0].setgenerate(True, 1) + self.sync_all() + + # Have node1 generate 100 blocks (so node0 can recover the fee) + self.nodes[1].setgenerate(True, 100) + self.sync_all() + + # node0 should end up with 100 btc in block rewards plus fees, but + # minus the 21 plus fees sent to node2 + assert_equal(self.nodes[0].getbalance(), 100-21) + assert_equal(self.nodes[2].getbalance(), 21) + + # Node0 should have two unspent outputs. + # Create a couple of transactions to send them to node2, submit them through + # node1, and make sure both node0 and node2 pick them up properly: + node0utxos = self.nodes[0].listunspent(1) + assert_equal(len(node0utxos), 2) + + # create both transactions + txns_to_send = [] + for utxo in node0utxos: + inputs = [] + outputs = {} + inputs.append({ "txid" : utxo["txid"], "vout" : utxo["vout"]}) + outputs[self.nodes[2].getnewaddress("from1")] = utxo["amount"] + raw_tx = self.nodes[0].createrawtransaction(inputs, outputs) + txns_to_send.append(self.nodes[0].signrawtransaction(raw_tx)) + + # Have node 1 (miner) send the transactions + self.nodes[1].sendrawtransaction(txns_to_send[0]["hex"], True) + self.nodes[1].sendrawtransaction(txns_to_send[1]["hex"], True) + + # Have node1 mine a block to confirm transactions: + self.nodes[1].setgenerate(True, 1) + self.sync_all() + + assert_equal(self.nodes[0].getbalance(), 0) + assert_equal(self.nodes[2].getbalance(), 100) + assert_equal(self.nodes[2].getbalance("from1"), 100-21) + + +if __name__ == '__main__': + WalletTest ().main () diff --git a/qa/rpc-tests/wallet.sh b/qa/rpc-tests/wallet.sh deleted file mode 100755 index c9ad0f2a78..0000000000 --- a/qa/rpc-tests/wallet.sh +++ /dev/null @@ -1,118 +0,0 @@ -#!/usr/bin/env bash -# Copyright (c) 2013-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. - -# Test block generation and basic wallet sending - -if [ $# -lt 1 ]; then - echo "Usage: $0 path_to_binaries" - echo "e.g. $0 ../../src" - echo "Env vars BITCOIND and BITCOINCLI may be used to specify the exact binaries used" - exit 1 -fi - -set -f - -BITCOIND=${BITCOIND:-${1}/bitcoind} -CLI=${BITCOINCLI:-${1}/bitcoin-cli} - -DIR="${BASH_SOURCE%/*}" -SENDANDWAIT="${DIR}/send.sh" -if [[ ! -d "$DIR" ]]; then DIR="$PWD"; fi -. "$DIR/util.sh" - -D=$(mktemp -d test.XXXXX) - -D1=${D}/node1 -CreateDataDir "$D1" port=11000 rpcport=11001 -B1ARGS="-datadir=$D1" -$BITCOIND $B1ARGS & -B1PID=$! - -D2=${D}/node2 -CreateDataDir "$D2" port=11010 rpcport=11011 connect=127.0.0.1:11000 -B2ARGS="-datadir=$D2" -$BITCOIND $B2ARGS & -B2PID=$! - -D3=${D}/node3 -CreateDataDir "$D3" port=11020 rpcport=11021 connect=127.0.0.1:11000 -B3ARGS="-datadir=$D3" -$BITCOIND $BITCOINDARGS $B3ARGS & -B3PID=$! - -# Wait until all three nodes are at the same block number -function WaitBlocks { - while : - do - sleep 1 - declare -i BLOCKS1=$( GetBlocks $B1ARGS ) - declare -i BLOCKS2=$( GetBlocks $B2ARGS ) - declare -i BLOCKS3=$( GetBlocks $B3ARGS ) - if (( BLOCKS1 == BLOCKS2 && BLOCKS2 == BLOCKS3 )) - then - break - fi - done -} - -echo "Generating test blockchain..." - -# 1 block, 50 XBT each == 50 XBT -$CLI $B1ARGS setgenerate true 1 -WaitBlocks -# 101 blocks, 1 mature == 50 XBT -$CLI $B2ARGS setgenerate true 101 -WaitBlocks - -CheckBalance "$B1ARGS" 50 -CheckBalance "$B2ARGS" 50 - -# Send 21 XBT from 1 to 3. Second -# transaction will be child of first, and -# will require a fee -Send $B1ARGS $B3ARGS 11 -Send $B1ARGS $B3ARGS 10 - -# Have B1 mine a new block, and mature it -# to recover transaction fees -$CLI $B1ARGS setgenerate true 1 -WaitBlocks - -# Have B2 mine 100 blocks so B1's block is mature: -$CLI $B2ARGS setgenerate true 100 -WaitBlocks - -# B1 should end up with 100 XBT in block rewards plus fees, -# minus the 21 XBT sent to B3: -CheckBalance "$B1ARGS" "100-21" -CheckBalance "$B3ARGS" "21" - -# B1 should have two unspent outputs; create a couple -# of raw transactions to send them to B3, submit them through -# B2, and make sure both B1 and B3 pick them up properly: -RAW1=$(CreateTxn1 $B1ARGS 1 $(Address $B3ARGS "from1" ) ) -RAW2=$(CreateTxn1 $B1ARGS 2 $(Address $B3ARGS "from1" ) ) -RAWTXID1=$(SendRawTxn "$B2ARGS" $RAW1) -RAWTXID2=$(SendRawTxn "$B2ARGS" $RAW2) - -# Have B2 mine a block to confirm transactions: -$CLI $B2ARGS setgenerate true 1 -WaitBlocks - -# Check balances after confirmation -CheckBalance "$B1ARGS" 0 -CheckBalance "$B3ARGS" 100 -CheckBalance "$B3ARGS" "100-21" "from1" - -$CLI $B3ARGS stop > /dev/null 2>&1 -wait $B3PID -$CLI $B2ARGS stop > /dev/null 2>&1 -wait $B2PID -$CLI $B1ARGS stop > /dev/null 2>&1 -wait $B1PID - -echo "Tests successful, cleaning up" -rm -rf $D -exit 0 diff --git a/src/Makefile.am b/src/Makefile.am index 556fd49c0b..0d45203c90 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -49,6 +49,13 @@ BITCOIN_INCLUDES += $(BDB_CPPFLAGS) noinst_LIBRARIES += libbitcoin_wallet.a endif +if BUILD_BITCOIN_LIBS +lib_LTLIBRARIES = libbitcoinconsensus.la +LIBBITCOIN_CONSENSUS=libbitcoinconsensus.la +else +LIBBITCOIN_CONSENSUS= +endif + bin_PROGRAMS = TESTS = @@ -295,7 +302,7 @@ endif bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) bitcoind_CPPFLAGS = $(BITCOIN_INCLUDES) -bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +bitcoind_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) # bitcoin-cli binary # bitcoin_cli_LDADD = \ @@ -324,12 +331,42 @@ bitcoin_tx_LDADD = \ bitcoin_tx_SOURCES = bitcoin-tx.cpp bitcoin_tx_CPPFLAGS = $(BITCOIN_INCLUDES) # -bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +bitcoin_tx_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) if TARGET_WINDOWS bitcoin_cli_SOURCES += bitcoin-cli-res.rc endif -bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +bitcoin_cli_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) + +if BUILD_BITCOIN_LIBS +include_HEADERS = script/bitcoinconsensus.h +libbitcoinconsensus_la_SOURCES = \ + core/transaction.cpp \ + crypto/sha1.cpp \ + crypto/sha2.cpp \ + crypto/ripemd160.cpp \ + eccryptoverify.cpp \ + ecwrapper.cpp \ + hash.cpp \ + pubkey.cpp \ + script/script.cpp \ + script/interpreter.cpp \ + script/bitcoinconsensus.cpp \ + uint256.cpp \ + utilstrencodings.cpp + +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 CLEANFILES = leveldb/libleveldb.a leveldb/libmemenv.a *.gcda *.gcno diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index fac214bdca..898337ad6f 100644 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -361,7 +361,7 @@ qt_bitcoin_qt_LDADD += $(LIBBITCOIN_WALLET) endif qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \ $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) -qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) +qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX #locale/foo.ts -> locale/foo.qm diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index 622411ca68..c5392cf307 100644 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -33,7 +33,7 @@ endif qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CRYPTO) $(LIBBITCOIN_UNIVALUE) $(LIBLEVELDB) \ $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \ $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) -qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) +qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 79509c9a3e..9e9f478d8f 100644 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -85,8 +85,8 @@ if ENABLE_WALLET test_test_bitcoin_LDADD += $(LIBBITCOIN_WALLET) endif -test_test_bitcoin_LDADD += $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) -test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) +test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) +test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static nodist_test_test_bitcoin_SOURCES = $(GENERATED_TEST_FILES) diff --git a/src/base58.cpp b/src/base58.cpp index d94db2c51b..c594993ea0 100644 --- a/src/base58.cpp +++ b/src/base58.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" @@ -15,7 +15,7 @@ #include <boost/variant/apply_visitor.hpp> #include <boost/variant/static_visitor.hpp> -/* All alphanumeric characters except for "0", "I", "O", and "l" */ +/** All alphanumeric characters except for "0", "I", "O", and "l" */ static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch) diff --git a/src/base58.h b/src/base58.h index 7cd2d651a1..c4cb96814c 100644 --- a/src/base58.h +++ b/src/base58.h @@ -1,16 +1,16 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -// -// Why base-58 instead of standard base-64 encoding? -// - Don't want 0OIl characters that look the same in some fonts and -// could be used to create visually identical looking account numbers. -// - A string with non-alphanumeric characters is not as easily accepted as an account number. -// - E-mail usually won't line-break if there's no punctuation to break at. -// - Double-clicking selects the whole number as one word if it's all alphanumeric. -// +/** + * Why base-58 instead of standard base-64 encoding? + * - Don't want 0OIl characters that look the same in some fonts and + * could be used to create visually identical looking account numbers. + * - A string with non-alphanumeric characters is not as easily accepted as an account number. + * - E-mail usually won't line-break if there's no punctuation to break at. + * - Double-clicking selects the whole number as one word if it's all alphanumeric. + */ #ifndef BITCOIN_BASE58_H #define BITCOIN_BASE58_H @@ -70,10 +70,10 @@ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char> class CBase58Data { protected: - // the version byte(s) + //! the version byte(s) std::vector<unsigned char> vchVersion; - // the actually encoded data + //! the actually encoded data typedef std::vector<unsigned char, zero_after_free_allocator<unsigned char> > vector_uchar; vector_uchar vchData; diff --git a/src/bloom.cpp b/src/bloom.cpp index df8cedaf6a..07b8f2c0ae 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "bloom.h" @@ -21,13 +21,17 @@ using namespace std; CBloomFilter::CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweakIn, unsigned char nFlagsIn) : -// The ideal size for a bloom filter with a given number of elements and false positive rate is: -// - nElements * log(fp rate) / ln(2)^2 -// We ignore filter parameters which will create a bloom filter larger than the protocol limits +/** + * The ideal size for a bloom filter with a given number of elements and false positive rate is: + * - nElements * log(fp rate) / ln(2)^2 + * We ignore filter parameters which will create a bloom filter larger than the protocol limits + */ vData(min((unsigned int)(-1 / LN2SQUARED * nElements * log(nFPRate)), MAX_BLOOM_FILTER_SIZE * 8) / 8), -// The ideal number of hash functions is filter size * ln(2) / number of elements -// Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits -// See http://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas +/** + * The ideal number of hash functions is filter size * ln(2) / number of elements + * Again, we ignore filter parameters which will create a bloom filter with more hash functions than the protocol limits + * See https://en.wikipedia.org/wiki/Bloom_filter for an explanation of these formulas + */ isFull(false), isEmpty(false), nHashFuncs(min((unsigned int)(vData.size() * 8 / nElements * LN2), MAX_HASH_FUNCS)), diff --git a/src/bloom.h b/src/bloom.h index 143e3b4c79..f54922edb9 100644 --- a/src/bloom.h +++ b/src/bloom.h @@ -1,5 +1,5 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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_BLOOM_H @@ -13,12 +13,14 @@ class COutPoint; class CTransaction; class uint256; -// 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001% +//! 20,000 items with fp rate < 0.1% or 10,000 items and <0.0001% static const unsigned int MAX_BLOOM_FILTER_SIZE = 36000; // bytes static const unsigned int MAX_HASH_FUNCS = 50; -// First two bits of nFlags control how much IsRelevantAndUpdate actually updates -// The remaining bits are reserved +/** + * First two bits of nFlags control how much IsRelevantAndUpdate actually updates + * The remaining bits are reserved + */ enum bloomflags { BLOOM_UPDATE_NONE = 0, @@ -52,13 +54,15 @@ private: unsigned int Hash(unsigned int nHashNum, const std::vector<unsigned char>& vDataToHash) const; public: - // Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements - // Note that if the given parameters will result in a filter outside the bounds of the protocol limits, - // the filter created will be as close to the given parameters as possible within the protocol limits. - // This will apply if nFPRate is very low or nElements is unreasonably high. - // nTweak is a constant which is added to the seed value passed to the hash function - // It should generally always be a random value (and is largely only exposed for unit testing) - // nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK) + /** + * Creates a new bloom filter which will provide the given fp rate when filled with the given number of elements + * Note that if the given parameters will result in a filter outside the bounds of the protocol limits, + * the filter created will be as close to the given parameters as possible within the protocol limits. + * This will apply if nFPRate is very low or nElements is unreasonably high. + * nTweak is a constant which is added to the seed value passed to the hash function + * It should generally always be a random value (and is largely only exposed for unit testing) + * nFlags should be one of the BLOOM_UPDATE_* enums (not _MASK) + */ CBloomFilter(unsigned int nElements, double nFPRate, unsigned int nTweak, unsigned char nFlagsIn); CBloomFilter() : isFull(true), isEmpty(false), nHashFuncs(0), nTweak(0), nFlags(0) {} @@ -82,14 +86,14 @@ public: void clear(); - // True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS - // (catch a filter which was just deserialized which was too big) + //! True if the size is <= MAX_BLOOM_FILTER_SIZE and the number of hash functions is <= MAX_HASH_FUNCS + //! (catch a filter which was just deserialized which was too big) bool IsWithinSizeConstraints() const; - // Also adds any outputs which match the filter to the filter (to match their spending txes) + //! Also adds any outputs which match the filter to the filter (to match their spending txes) bool IsRelevantAndUpdate(const CTransaction& tx); - // Checks for empty and full filters to avoid wasting cpu + //! Checks for empty and full filters to avoid wasting cpu void UpdateEmptyFull(); }; diff --git a/src/chain.h b/src/chain.h index f99fd113b7..c01240665d 100644 --- a/src/chain.h +++ b/src/chain.h @@ -220,11 +220,6 @@ public: return (int64_t)nTime; } - uint256 GetBlockWork() const - { - return GetProofIncrement(nBits); - } - enum { nMedianTimeSpan=11 }; int64_t GetMedianTimePast() const diff --git a/src/chainparams.cpp b/src/chainparams.cpp index e539eb7bd7..8a6a061ea1 100644 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -192,11 +192,6 @@ public: CTestNetParams() { networkID = CBaseChainParams::TESTNET; strNetworkID = "test"; - /** - * The message start string is designed to be unlikely to occur in normal data. - * The characters are rarely used upper ASCII, not valid as UTF-8, and produce - * a large 4-byte int at any alignment. - */ pchMessageStart[0] = 0x0b; pchMessageStart[1] = 0x11; pchMessageStart[2] = 0x09; diff --git a/src/checkpoints.cpp b/src/checkpoints.cpp index fbde47339d..0fb4411e63 100644 --- a/src/checkpoints.cpp +++ b/src/checkpoints.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "checkpoints.h" @@ -14,11 +14,13 @@ namespace Checkpoints { - // How many times we expect transactions after the last checkpoint to - // be slower. This number is a compromise, as it can't be accurate for - // every system. When reindexing from a fast disk with a slow CPU, it - // can be up to 20, while when downloading from a slow network with a - // fast multicore CPU, it won't be much higher than 1. + /** + * How many times we expect transactions after the last checkpoint to + * be slower. This number is a compromise, as it can't be accurate for + * every system. When reindexing from a fast disk with a slow CPU, it + * can be up to 20, while when downloading from a slow network with a + * fast multicore CPU, it won't be much higher than 1. + */ static const double SIGCHECK_VERIFICATION_FACTOR = 5.0; bool fEnabled = true; @@ -35,7 +37,7 @@ namespace Checkpoints { return hash == i->second; } - // Guess how far we are in the verification process at the given block index + //! Guess how far we are in the verification process at the given block index double GuessVerificationProgress(CBlockIndex *pindex, bool fSigchecks) { if (pindex==NULL) return 0.0; diff --git a/src/checkpoints.h b/src/checkpoints.h index 847524a9f2..65c5165f0f 100644 --- a/src/checkpoints.h +++ b/src/checkpoints.h @@ -1,5 +1,5 @@ -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_CHECKPOINTS_H @@ -11,7 +11,8 @@ class CBlockIndex; -/** Block-chain checkpoints are compiled-in sanity checks. +/** + * Block-chain checkpoints are compiled-in sanity checks. * They are updated every release or three. */ namespace Checkpoints @@ -25,13 +26,13 @@ struct CCheckpointData { double fTransactionsPerDay; }; -// Returns true if block passes checkpoint checks +//! Returns true if block passes checkpoint checks bool CheckBlock(int nHeight, const uint256& hash); -// Return conservative estimate of total number of blocks, 0 if unknown +//! Return conservative estimate of total number of blocks, 0 if unknown int GetTotalBlocksEstimate(); -// Returns last CBlockIndex* in mapBlockIndex that is a checkpoint +//! Returns last CBlockIndex* in mapBlockIndex that is a checkpoint CBlockIndex* GetLastCheckpoint(); double GuessVerificationProgress(CBlockIndex* pindex, bool fSigchecks = true); diff --git a/src/checkqueue.h b/src/checkqueue.h index afecfeede5..2ee46a1210 100644 --- a/src/checkqueue.h +++ b/src/checkqueue.h @@ -1,5 +1,5 @@ -// Copyright (c) 2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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_CHECKQUEUE_H @@ -16,7 +16,8 @@ template <typename T> class CCheckQueueControl; -/** Queue for verifications that have to be performed. +/** + * Queue for verifications that have to be performed. * The verifications are represented by a type T, which must provide an * operator(), returning a bool. * @@ -29,40 +30,42 @@ template <typename T> class CCheckQueue { private: - // Mutex to protect the inner state + //! Mutex to protect the inner state boost::mutex mutex; - // Worker threads block on this when out of work + //! Worker threads block on this when out of work boost::condition_variable condWorker; - // Master thread blocks on this when out of work + //! Master thread blocks on this when out of work boost::condition_variable condMaster; - // The queue of elements to be processed. - // As the order of booleans doesn't matter, it is used as a LIFO (stack) + //! The queue of elements to be processed. + //! As the order of booleans doesn't matter, it is used as a LIFO (stack) std::vector<T> queue; - // The number of workers (including the master) that are idle. + //! The number of workers (including the master) that are idle. int nIdle; - // The total number of workers (including the master). + //! The total number of workers (including the master). int nTotal; - // The temporary evaluation result. + //! The temporary evaluation result. bool fAllOk; - // Number of verifications that haven't completed yet. - // This includes elements that are not anymore in queue, but still in - // worker's own batches. + /** + * Number of verifications that haven't completed yet. + * This includes elements that are not anymore in queue, but still in + * worker's own batches. + */ unsigned int nTodo; - // Whether we're shutting down. + //! Whether we're shutting down. bool fQuit; - // The maximum number of elements to be processed in one batch + //! The maximum number of elements to be processed in one batch unsigned int nBatchSize; - // Internal function that does bulk of the verification work. + /** Internal function that does bulk of the verification work. */ bool Loop(bool fMaster = false) { boost::condition_variable& cond = fMaster ? condMaster : condWorker; @@ -124,22 +127,22 @@ private: } public: - // Create a new check queue + //! Create a new check queue CCheckQueue(unsigned int nBatchSizeIn) : nIdle(0), nTotal(0), fAllOk(true), nTodo(0), fQuit(false), nBatchSize(nBatchSizeIn) {} - // Worker thread + //! Worker thread void Thread() { Loop(); } - // Wait until execution finishes, and return whether all evaluations where succesful. + //! Wait until execution finishes, and return whether all evaluations where successful. bool Wait() { return Loop(true); } - // Add a batch of checks to the queue + //! Add a batch of checks to the queue void Add(std::vector<T>& vChecks) { boost::unique_lock<boost::mutex> lock(mutex); @@ -161,8 +164,9 @@ public: friend class CCheckQueueControl<T>; }; -/** RAII-style controller object for a CCheckQueue that guarantees the passed - * queue is finished before continuing. +/** + * RAII-style controller object for a CCheckQueue that guarantees the passed + * queue is finished before continuing. */ template <typename T> class CCheckQueueControl diff --git a/src/coins.cpp b/src/coins.cpp index e4f3e67aeb..c2e802c953 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -1,5 +1,5 @@ -// Copyright (c) 2012-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "coins.h" @@ -8,9 +8,11 @@ #include <assert.h> -// calculate number of bytes for the bitmask, and its number of non-zero bytes -// each bit in the bitmask represents the availability of one output, but the -// availabilities of the first two outputs are encoded separately +/** + * calculate number of bytes for the bitmask, and its number of non-zero bytes + * each bit in the bitmask represents the availability of one output, but the + * availabilities of the first two outputs are encoded separately + */ void CCoins::CalcMaskSize(unsigned int &nBytes, unsigned int &nNonzeroBytes) const { unsigned int nLastUsedByte = 0; for (unsigned int b = 0; 2+b*8 < vout.size(); b++) { @@ -133,7 +135,7 @@ const CCoins* CCoinsViewCache::AccessCoins(const uint256 &txid) const { bool CCoinsViewCache::HaveCoins(const uint256 &txid) const { CCoinsMap::const_iterator it = FetchCoins(txid); // We're using vtx.empty() instead of IsPruned here for performance reasons, - // as we only care about the case where an transaction was replaced entirely + // as we only care about the case where a transaction was replaced entirely // in a reorganization (which wipes vout entirely, as opposed to spending // which just cleans individual outputs). return (it != cacheCoins.end() && !it->second.coins.vout.empty()); diff --git a/src/coins.h b/src/coins.h index ee9051562b..dbe3f8bd31 100644 --- a/src/coins.h +++ b/src/coins.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_COINS_H @@ -17,7 +17,8 @@ #include <boost/foreach.hpp> #include <boost/unordered_map.hpp> -/** pruned version of CTransaction: only retains metadata and unspent transaction outputs +/** + * Pruned version of CTransaction: only retains metadata and unspent transaction outputs * * Serialized format: * - VARINT(nVersion) @@ -71,17 +72,17 @@ class CCoins { public: - // whether transaction is a coinbase + //! whether transaction is a coinbase bool fCoinBase; - // unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped + //! unspent transaction outputs; spent outputs are .IsNull(); spent outputs at the end of the array are dropped std::vector<CTxOut> vout; - // at which height this transaction was included in the active block chain + //! at which height this transaction was included in the active block chain int nHeight; - // version of the CTransaction; accesses to this value should probably check for nHeight as well, - // as new tx version will probably only be introduced at certain heights + //! version of the CTransaction; accesses to this value should probably check for nHeight as well, + //! as new tx version will probably only be introduced at certain heights int nVersion; void FromTx(const CTransaction &tx, int nHeightIn) { @@ -92,7 +93,7 @@ public: ClearUnspendable(); } - // construct a CCoins from a CTransaction, at a given height + //! construct a CCoins from a CTransaction, at a given height CCoins(const CTransaction &tx, int nHeightIn) { FromTx(tx, nHeightIn); } @@ -104,10 +105,10 @@ public: nVersion = 0; } - // empty constructor + //! empty constructor CCoins() : fCoinBase(false), vout(0), nHeight(0), nVersion(0) { } - // remove spent outputs at the end of vout + //!remove spent outputs at the end of vout void Cleanup() { while (vout.size() > 0 && vout.back().IsNull()) vout.pop_back(); @@ -130,7 +131,7 @@ public: std::swap(to.nVersion, nVersion); } - // equality test + //! equality test friend bool operator==(const CCoins &a, const CCoins &b) { // Empty CCoins objects are always equal. if (a.IsPruned() && b.IsPruned()) @@ -236,19 +237,19 @@ public: Cleanup(); } - // mark an outpoint spent, and construct undo information + //! mark an outpoint spent, and construct undo information bool Spend(const COutPoint &out, CTxInUndo &undo); - // mark a vout spent + //! mark a vout spent bool Spend(int nPos); - // check whether a particular output is still available + //! check whether a particular output is still available bool IsAvailable(unsigned int nPos) const { return (nPos < vout.size() && !vout[nPos].IsNull()); } - // check whether the entire CCoins is spent - // note that only !IsPruned() CCoins can be serialized + //! check whether the entire CCoins is spent + //! note that only !IsPruned() CCoins can be serialized bool IsPruned() const { BOOST_FOREACH(const CTxOut &out, vout) if (!out.IsNull()) @@ -264,9 +265,12 @@ private: public: CCoinsKeyHasher(); - // This *must* return size_t. With Boost 1.46 on 32-bit systems the - // unordered_map will behave unpredictably if the custom hasher returns a - // uint64_t, resulting in failures when syncing the chain (#4634). + + /** + * This *must* return size_t. With Boost 1.46 on 32-bit systems the + * unordered_map will behave unpredictably if the custom hasher returns a + * uint64_t, resulting in failures when syncing the chain (#4634). + */ size_t operator()(const uint256& key) const { return key.GetHash(salt); } @@ -305,24 +309,24 @@ struct CCoinsStats class CCoinsView { public: - // Retrieve the CCoins (unspent transaction outputs) for a given txid + //! Retrieve the CCoins (unspent transaction outputs) for a given txid virtual bool GetCoins(const uint256 &txid, CCoins &coins) const; - // Just check whether we have data for a given txid. - // This may (but cannot always) return true for fully spent transactions + //! Just check whether we have data for a given txid. + //! This may (but cannot always) return true for fully spent transactions virtual bool HaveCoins(const uint256 &txid) const; - // Retrieve the block hash whose state this CCoinsView currently represents + //! Retrieve the block hash whose state this CCoinsView currently represents virtual uint256 GetBestBlock() const; - // Do a bulk modification (multiple CCoins changes + BestBlock change). - // The passed mapCoins can be modified. + //! Do a bulk modification (multiple CCoins changes + BestBlock change). + //! The passed mapCoins can be modified. virtual bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); - // Calculate statistics about the unspent transaction output set + //! Calculate statistics about the unspent transaction output set virtual bool GetStats(CCoinsStats &stats) const; - // As we use CCoinsViews polymorphically, have a virtual destructor + //! As we use CCoinsViews polymorphically, have a virtual destructor virtual ~CCoinsView() {} }; @@ -346,9 +350,11 @@ public: class CCoinsViewCache; -/** A reference to a mutable cache entry. Encapsulating it allows us to run +/** + * A reference to a mutable cache entry. Encapsulating it allows us to run * cleanup code after the modification is finished, and keeping track of - * concurrent modifications. */ + * concurrent modifications. + */ class CCoinsModifier { private: @@ -370,8 +376,10 @@ protected: /* Whether this cache has an active modifier. */ bool hasModifier; - /* Make mutable so that we can "fill the cache" even from Get-methods - declared as "const". */ + /** + * Make mutable so that we can "fill the cache" even from Get-methods + * declared as "const". + */ mutable uint256 hashBlock; mutable CCoinsMap cacheCoins; @@ -386,37 +394,44 @@ public: void SetBestBlock(const uint256 &hashBlock); bool BatchWrite(CCoinsMap &mapCoins, const uint256 &hashBlock); - // Return a pointer to CCoins in the cache, or NULL if not found. This is - // more efficient than GetCoins. Modifications to other cache entries are - // allowed while accessing the returned pointer. + /** + * Return a pointer to CCoins in the cache, or NULL if not found. This is + * more efficient than GetCoins. Modifications to other cache entries are + * allowed while accessing the returned pointer. + */ const CCoins* AccessCoins(const uint256 &txid) const; - // Return a modifiable reference to a CCoins. If no entry with the given - // txid exists, a new one is created. Simultaneous modifications are not - // allowed. + /** + * Return a modifiable reference to a CCoins. If no entry with the given + * txid exists, a new one is created. Simultaneous modifications are not + * allowed. + */ CCoinsModifier ModifyCoins(const uint256 &txid); - // Push the modifications applied to this cache to its base. - // Failure to call this method before destruction will cause the changes to be forgotten. - // If false is returned, the state of this cache (and its backing view) will be undefined. + /** + * Push the modifications applied to this cache to its base. + * Failure to call this method before destruction will cause the changes to be forgotten. + * If false is returned, the state of this cache (and its backing view) will be undefined. + */ bool Flush(); - // Calculate the size of the cache (in number of transactions) + //! Calculate the size of the cache (in number of transactions) unsigned int GetCacheSize() const; - /** Amount of bitcoins coming in to a transaction - Note that lightweight clients may not know anything besides the hash of previous transactions, - so may not be able to calculate this. - - @param[in] tx transaction for which we are checking input total - @return Sum of value of all inputs (scriptSigs) + /** + * Amount of bitcoins coming in to a transaction + * Note that lightweight clients may not know anything besides the hash of previous transactions, + * so may not be able to calculate this. + * + * @param[in] tx transaction for which we are checking input total + * @return Sum of value of all inputs (scriptSigs) */ CAmount GetValueIn(const CTransaction& tx) const; - // Check whether all prevouts of the transaction are present in the UTXO set represented by this view + //! Check whether all prevouts of the transaction are present in the UTXO set represented by this view bool HaveInputs(const CTransaction& tx) const; - // Return priority of tx at height nHeight + //! Return priority of tx at height nHeight double GetPriority(const CTransaction &tx, int nHeight) const; const CTxOut &GetOutputFor(const CTxIn& input) const; diff --git a/src/compressor.h b/src/compressor.h index 226be620e8..d9cde5de7a 100644 --- a/src/compressor.h +++ b/src/compressor.h @@ -28,19 +28,23 @@ class CScriptID; class CScriptCompressor { private: - // make this static for now (there are only 6 special scripts defined) - // this can potentially be extended together with a new nVersion for - // transactions, in which case this value becomes dependent on nVersion - // and nHeight of the enclosing transaction. + /** + * make this static for now (there are only 6 special scripts defined) + * this can potentially be extended together with a new nVersion for + * transactions, in which case this value becomes dependent on nVersion + * and nHeight of the enclosing transaction. + */ static const unsigned int nSpecialScripts = 6; CScript &script; protected: - // These check for scripts for which a special case with a shorter encoding is defined. - // They are implemented separately from the CScript test, as these test for exact byte - // sequence correspondences, and are more strict. For example, IsToPubKey also verifies - // whether the public key is valid (as invalid ones cannot be represented in compressed - // form). + /** + * These check for scripts for which a special case with a shorter encoding is defined. + * They are implemented separately from the CScript test, as these test for exact byte + * sequence correspondences, and are more strict. For example, IsToPubKey also verifies + * whether the public key is valid (as invalid ones cannot be represented in compressed + * form). + */ bool IsToKeyID(CKeyID &hash) const; bool IsToScriptID(CScriptID &hash) const; bool IsToPubKey(CPubKey &pubkey) const; diff --git a/src/core_io.h b/src/core_io.h index b5ed03b8c8..aba1928a36 100644 --- a/src/core_io.h +++ b/src/core_io.h @@ -8,6 +8,7 @@ #include <string> #include <vector> +class CBlock; class CScript; class CTransaction; class uint256; @@ -16,6 +17,7 @@ class UniValue; // core_read.cpp extern CScript ParseScript(std::string s); extern bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx); +extern bool DecodeHexBlk(CBlock&, const std::string& strHexBlk); extern uint256 ParseHashUV(const UniValue& v, const std::string& strName); extern std::vector<unsigned char> ParseHexUV(const UniValue& v, const std::string& strName); diff --git a/src/core_read.cpp b/src/core_read.cpp index d39bc9a780..42e2f8d200 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -4,6 +4,7 @@ #include "core_io.h" +#include "core/block.h" #include "core/transaction.h" #include "script/script.h" #include "serialize.h" @@ -108,6 +109,23 @@ bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx) return true; } +bool DecodeHexBlk(CBlock& block, const std::string& strHexBlk) +{ + if (!IsHex(strHexBlk)) + return false; + + std::vector<unsigned char> blockData(ParseHex(strHexBlk)); + CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION); + try { + ssBlock >> block; + } + catch (const std::exception &) { + return false; + } + + return true; +} + uint256 ParseHashUV(const UniValue& v, const string& strName) { string strHex; diff --git a/src/crypter.h b/src/crypter.h index b589987c4f..f7018cfdbe 100644 --- a/src/crypter.h +++ b/src/crypter.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009-2013 The Bitcoin developers +// Copyright (c) 2009-2014 The Bitcoin developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -14,20 +14,20 @@ class uint256; const unsigned int WALLET_CRYPTO_KEY_SIZE = 32; const unsigned int WALLET_CRYPTO_SALT_SIZE = 8; -/* -Private key encryption is done based on a CMasterKey, -which holds a salt and random encryption key. - -CMasterKeys are encrypted using AES-256-CBC using a key -derived using derivation method nDerivationMethod -(0 == EVP_sha512()) and derivation iterations nDeriveIterations. -vchOtherDerivationParameters is provided for alternative algorithms -which may require more parameters (such as scrypt). - -Wallet Private Keys are then encrypted using AES-256-CBC -with the double-sha256 of the public key as the IV, and the -master key's key as the encryption key (see keystore.[ch]). -*/ +/** + * Private key encryption is done based on a CMasterKey, + * which holds a salt and random encryption key. + * + * CMasterKeys are encrypted using AES-256-CBC using a key + * derived using derivation method nDerivationMethod + * (0 == EVP_sha512()) and derivation iterations nDeriveIterations. + * vchOtherDerivationParameters is provided for alternative algorithms + * which may require more parameters (such as scrypt). + * + * Wallet Private Keys are then encrypted using AES-256-CBC + * with the double-sha256 of the public key as the IV, and the + * master key's key as the encryption key (see keystore.[ch]). + */ /** Master key for wallet encryption */ class CMasterKey @@ -35,12 +35,12 @@ class CMasterKey public: std::vector<unsigned char> vchCryptedKey; std::vector<unsigned char> vchSalt; - // 0 = EVP_sha512() - // 1 = scrypt() + //! 0 = EVP_sha512() + //! 1 = scrypt() unsigned int nDerivationMethod; unsigned int nDeriveIterations; - // Use this for more parameters to key derivation, - // such as the various parameters to scrypt + //! Use this for more parameters to key derivation, + //! such as the various parameters to scrypt std::vector<unsigned char> vchOtherDerivationParameters; ADD_SERIALIZE_METHODS; @@ -120,17 +120,17 @@ private: CKeyingMaterial vMasterKey; - // if fUseCrypto is true, mapKeys must be empty - // if fUseCrypto is false, vMasterKey must be empty + //! if fUseCrypto is true, mapKeys must be empty + //! if fUseCrypto is false, vMasterKey must be empty bool fUseCrypto; - // keeps track of whether Unlock has run a thourough check before + //! keeps track of whether Unlock has run a thorough check before bool fDecryptionThoroughlyChecked; protected: bool SetCrypted(); - // will encrypt previously unencrypted keys + //! will encrypt previously unencrypted keys bool EncryptKeys(CKeyingMaterial& vMasterKeyIn); bool Unlock(const CKeyingMaterial& vMasterKeyIn); @@ -189,7 +189,8 @@ public: } } - /* Wallet status (encrypted, locked) changed. + /** + * Wallet status (encrypted, locked) changed. * Note: Called without locks held. */ boost::signals2::signal<void (CCryptoKeyStore* wallet)> NotifyStatusChanged; @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_DB_H @@ -50,7 +50,7 @@ public: void MakeMock(); bool IsMock() { return fMockDb; } - /* + /** * Verify that database file strFile is OK. If it is not, * call the callback to try to recover. * This must be called BEFORE strFile is opened. @@ -60,7 +60,7 @@ public: RECOVER_OK, RECOVER_FAIL }; VerifyResult Verify(std::string strFile, bool (*recoverFunc)(CDBEnv& dbenv, std::string strFile)); - /* + /** * Salvage data from a file that Verify says is bad. * fAggressive sets the DB_AGGRESSIVE flag (see berkeley DB->verify() method documentation). * Appends binary key/value pairs to vResult, returns true if successful. diff --git a/src/ecwrapper.cpp b/src/ecwrapper.cpp index 68cdbf2eda..5ce7e61294 100644 --- a/src/ecwrapper.cpp +++ b/src/ecwrapper.cpp @@ -13,9 +13,11 @@ namespace { -// Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields -// recid selects which key is recovered -// if check is non-zero, additional checks are performed +/** + * Perform ECDSA key recovery (see SEC1 4.1.6) for curves over (mod p)-fields + * recid selects which key is recovered + * if check is non-zero, additional checks are performed + */ int ECDSA_SIG_recover_key_GFp(EC_KEY *eckey, ECDSA_SIG *ecsig, const unsigned char *msg, int msglen, int recid, int check) { if (!eckey) return 0; diff --git a/src/ecwrapper.h b/src/ecwrapper.h index 30c3db7931..4efde51650 100644 --- a/src/ecwrapper.h +++ b/src/ecwrapper.h @@ -12,7 +12,7 @@ class uint256; -// RAII Wrapper around OpenSSL's EC_KEY +/** RAII Wrapper around OpenSSL's EC_KEY */ class CECKey { private: EC_KEY *pkey; @@ -25,10 +25,12 @@ public: bool SetPubKey(const unsigned char* pubkey, size_t size); bool Verify(const uint256 &hash, const std::vector<unsigned char>& vchSig); - // reconstruct public key from a compact signature - // This is only slightly more CPU intensive than just verifying it. - // If this function succeeds, the recovered public key is guaranteed to be valid - // (the signature is a valid signature of the given data for that key) + /** + * reconstruct public key from a compact signature + * This is only slightly more CPU intensive than just verifying it. + * If this function succeeds, the recovered public key is guaranteed to be valid + * (the signature is a valid signature of the given data for that key) + */ bool Recover(const uint256 &hash, const unsigned char *p64, int rec); bool TweakPublic(const unsigned char vchTweak[32]); diff --git a/src/init.cpp b/src/init.cpp index 4a9982a1cd..d2d6858618 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -379,7 +379,7 @@ std::string LicenseInfo() "\n" + FormatParagraph(_("This is experimental software.")) + "\n" + "\n" + - FormatParagraph(_("Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" + + FormatParagraph(_("Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.")) + "\n" + "\n" + FormatParagraph(_("This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.")) + "\n"; @@ -854,10 +854,8 @@ bool AppInit2(boost::thread_group& threadGroup) if (!addrProxy.IsValid()) return InitError(strprintf(_("Invalid -proxy address: '%s'"), mapArgs["-proxy"])); - if (!IsLimited(NET_IPV4)) - SetProxy(NET_IPV4, addrProxy); - if (!IsLimited(NET_IPV6)) - SetProxy(NET_IPV6, addrProxy); + SetProxy(NET_IPV4, addrProxy); + SetProxy(NET_IPV6, addrProxy); SetNameProxy(addrProxy); fProxy = true; } diff --git a/src/key.cpp b/src/key.cpp index 76256b864c..a91ed1cc1d 100644 --- a/src/key.cpp +++ b/src/key.cpp @@ -86,6 +86,20 @@ bool CKey::Sign(const uint256 &hash, std::vector<unsigned char>& vchSig) const { return true; } +bool CKey::VerifyPubKey(const CPubKey& pubkey) const { + if (pubkey.IsCompressed() != fCompressed) { + return false; + } + unsigned char rnd[8]; + std::string str = "Bitcoin key verification\n"; + GetRandBytes(rnd, sizeof(rnd)); + uint256 hash; + CHash256().Write((unsigned char*)str.data(), str.size()).Write(rnd, sizeof(rnd)).Finalize((unsigned char*)&hash); + std::vector<unsigned char> vchSig; + Sign(hash, vchSig); + return pubkey.Verify(hash, vchSig); +} + bool CKey::SignCompact(const uint256 &hash, std::vector<unsigned char>& vchSig) const { if (!fValid) return false; @@ -111,10 +125,7 @@ bool CKey::Load(CPrivKey &privkey, CPubKey &vchPubKey, bool fSkipCheck=false) { if (fSkipCheck) return true; - if (GetPubKey() != vchPubKey) - return false; - - return true; + return VerifyPubKey(vchPubKey); } bool CKey::Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const { @@ -190,5 +201,13 @@ void CExtKey::Decode(const unsigned char code[74]) { } bool ECC_InitSanityCheck() { - return CECKey::SanityCheck(); +#if !defined(USE_SECP256K1) + if (!CECKey::SanityCheck()) { + return false; + } +#endif + CKey key; + key.MakeNewKey(true); + CPubKey pubkey = key.GetPubKey(); + return key.VerifyPubKey(pubkey); } @@ -13,9 +13,10 @@ #include <stdexcept> #include <vector> -struct CExtPubKey; class CPubKey; +struct CExtPubKey; + /** * secp256k1: * const unsigned int PRIVATE_KEY_SIZE = 279; @@ -136,6 +137,12 @@ public: //! Derive BIP32 child key. bool Derive(CKey& keyChild, unsigned char ccChild[32], unsigned int nChild, const unsigned char cc[32]) const; + /** + * Verify thoroughly whether a private key and a public key match. + * This is done using a different mechanism than just regenerating it. + */ + bool VerifyPubKey(const CPubKey& vchPubKey) const; + //! Load private key and check that public key matches. bool Load(CPrivKey& privkey, CPubKey& vchPubKey, bool fSkipCheck); diff --git a/src/leveldbwrapper.h b/src/leveldbwrapper.h index 10b7a2427c..42479206c8 100644 --- a/src/leveldbwrapper.h +++ b/src/leveldbwrapper.h @@ -1,5 +1,5 @@ -// Copyright (c) 2012-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2012-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_LEVELDBWRAPPER_H @@ -24,7 +24,7 @@ public: void HandleError(const leveldb::Status& status) throw(leveldb_error); -// Batch of changes queued to be written to a CLevelDBWrapper +/** Batch of changes queued to be written to a CLevelDBWrapper */ class CLevelDBBatch { friend class CLevelDBWrapper; @@ -64,25 +64,25 @@ public: class CLevelDBWrapper { private: - // custom environment this database is using (may be NULL in case of default environment) + //! custom environment this database is using (may be NULL in case of default environment) leveldb::Env* penv; - // database options used + //! database options used leveldb::Options options; - // options used when reading from the database + //! options used when reading from the database leveldb::ReadOptions readoptions; - // options used when iterating over values of the database + //! options used when iterating over values of the database leveldb::ReadOptions iteroptions; - // options used when writing to the database + //! options used when writing to the database leveldb::WriteOptions writeoptions; - // options used when sync writing to the database + //! options used when sync writing to the database leveldb::WriteOptions syncoptions; - // the database itself + //! the database itself leveldb::DB* pdb; public: diff --git a/src/main.cpp b/src/main.cpp index 2bff781bfa..88cb9c5b26 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1226,15 +1226,15 @@ void CheckForkWarningConditions() if (pindexBestForkTip && chainActive.Height() - pindexBestForkTip->nHeight >= 72) pindexBestForkTip = NULL; - if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (chainActive.Tip()->GetBlockWork() * 6))) + if (pindexBestForkTip || (pindexBestInvalid && pindexBestInvalid->nChainWork > chainActive.Tip()->nChainWork + (GetBlockProof(*chainActive.Tip()) * 6))) { - if (!fLargeWorkForkFound) + if (!fLargeWorkForkFound && pindexBestForkBase) { std::string warning = std::string("'Warning: Large-work fork detected, forking after block ") + pindexBestForkBase->phashBlock->ToString() + std::string("'"); CAlert::Notify(warning, true); } - if (pindexBestForkTip) + if (pindexBestForkTip && pindexBestForkBase) { LogPrintf("CheckForkWarningConditions: Warning: Large valid fork found\n forking the chain at height %d (%s)\n lasting to height %d (%s).\nChain state database corruption likely.\n", pindexBestForkBase->nHeight, pindexBestForkBase->phashBlock->ToString(), @@ -1277,7 +1277,7 @@ void CheckForkWarningConditionsOnNewFork(CBlockIndex* pindexNewForkTip) // We define it this way because it allows us to only store the highest fork tip (+ base) which meets // the 7-block condition and from this always have the most-likely-to-cause-warning fork if (pfork && (!pindexBestForkTip || (pindexBestForkTip && pindexNewForkTip->nHeight > pindexBestForkTip->nHeight)) && - pindexNewForkTip->nChainWork - pfork->nChainWork > (pfork->GetBlockWork() * 7) && + pindexNewForkTip->nChainWork - pfork->nChainWork > (GetBlockProof(*pfork) * 7) && chainActive.Height() - pindexNewForkTip->nHeight < 72) { pindexBestForkTip = pindexNewForkTip; @@ -1593,7 +1593,7 @@ static int64_t nTimeIndex = 0; static int64_t nTimeCallbacks = 0; static int64_t nTimeTotal = 0; -bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& view, bool fJustCheck) { AssertLockHeld(cs_main); // Check it again in case a previous version let a bad block in @@ -2118,7 +2118,7 @@ CBlockIndex* AddToBlockIndex(const CBlockHeader& block) pindexNew->nHeight = pindexNew->pprev->nHeight + 1; pindexNew->BuildSkip(); } - pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + pindexNew->GetBlockWork(); + pindexNew->nChainWork = (pindexNew->pprev ? pindexNew->pprev->nChainWork : 0) + GetBlockProof(*pindexNew); pindexNew->RaiseValidity(BLOCK_VALID_TREE); if (pindexBestHeader == NULL || pindexBestHeader->nChainWork < pindexNew->nChainWork) pindexBestHeader = pindexNew; @@ -2280,6 +2280,8 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo { // These are checks that are independent of context. + // Check that the header is valid (particularly PoW). This is mostly + // redundant with the call in AcceptBlockHeader. if (!CheckBlockHeader(block, state, fCheckPOW)) return false; @@ -2334,6 +2336,73 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo return true; } +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex * const pindexPrev) +{ + uint256 hash = block.GetHash(); + if (hash == Params().HashGenesisBlock()) + return true; + + assert(pindexPrev); + + int nHeight = pindexPrev->nHeight+1; + + // Check proof of work + if ((!Params().SkipProofOfWorkCheck()) && + (block.nBits != GetNextWorkRequired(pindexPrev, &block))) + return state.DoS(100, error("%s : incorrect proof of work", __func__), + REJECT_INVALID, "bad-diffbits"); + + // Check timestamp against prev + if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) + return state.Invalid(error("%s : block's timestamp is too early", __func__), + REJECT_INVALID, "time-too-old"); + + // Check that the block chain matches the known block chain up to a checkpoint + if (!Checkpoints::CheckBlock(nHeight, hash)) + return state.DoS(100, error("%s : rejected by checkpoint lock-in at %d", __func__, nHeight), + REJECT_CHECKPOINT, "checkpoint mismatch"); + + // Don't accept any forks from the main chain prior to last checkpoint + CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); + if (pcheckpoint && nHeight < pcheckpoint->nHeight) + return state.DoS(100, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight)); + + // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: + if (block.nVersion < 2 && + CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) + { + return state.Invalid(error("%s : rejected nVersion=1 block", __func__), + REJECT_OBSOLETE, "bad-version"); + } + + return true; +} + +bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex * const pindexPrev) +{ + const int nHeight = pindexPrev == NULL ? 0 : pindexPrev->nHeight + 1; + + // Check that all transactions are finalized + BOOST_FOREACH(const CTransaction& tx, block.vtx) + if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { + return state.DoS(10, error("%s : contains a non-final transaction", __func__), REJECT_INVALID, "bad-txns-nonfinal"); + } + + // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height + // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): + if (block.nVersion >= 2 && + CBlockIndex::IsSuperMajority(2, pindexPrev, Params().EnforceBlockUpgradeMajority())) + { + CScript expect = CScript() << nHeight; + if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || + !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { + return state.DoS(100, error("%s : block height mismatch in coinbase", __func__), REJECT_INVALID, "bad-cb-height"); + } + } + + return true; +} + bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex** ppindex) { AssertLockHeld(cs_main); @@ -2351,46 +2420,21 @@ bool AcceptBlockHeader(const CBlockHeader& block, CValidationState& state, CBloc return true; } + if (!CheckBlockHeader(block, state)) + return false; + // Get prev block index CBlockIndex* pindexPrev = NULL; - int nHeight = 0; if (hash != Params().HashGenesisBlock()) { BlockMap::iterator mi = mapBlockIndex.find(block.hashPrevBlock); if (mi == mapBlockIndex.end()) return state.DoS(10, error("%s : prev block not found", __func__), 0, "bad-prevblk"); pindexPrev = (*mi).second; - nHeight = pindexPrev->nHeight+1; - - // Check proof of work - if ((!Params().SkipProofOfWorkCheck()) && - (block.nBits != GetNextWorkRequired(pindexPrev, &block))) - return state.DoS(100, error("%s : incorrect proof of work", __func__), - REJECT_INVALID, "bad-diffbits"); - - // Check timestamp against prev - if (block.GetBlockTime() <= pindexPrev->GetMedianTimePast()) - return state.Invalid(error("%s : block's timestamp is too early", __func__), - REJECT_INVALID, "time-too-old"); - - // Check that the block chain matches the known block chain up to a checkpoint - if (!Checkpoints::CheckBlock(nHeight, hash)) - return state.DoS(100, error("%s : rejected by checkpoint lock-in at %d", __func__, nHeight), - REJECT_CHECKPOINT, "checkpoint mismatch"); - - // Don't accept any forks from the main chain prior to last checkpoint - CBlockIndex* pcheckpoint = Checkpoints::GetLastCheckpoint(); - if (pcheckpoint && nHeight < pcheckpoint->nHeight) - return state.DoS(100, error("%s : forked chain older than last checkpoint (height %d)", __func__, nHeight)); - - // Reject block.nVersion=1 blocks when 95% (75% on testnet) of the network has upgraded: - if (block.nVersion < 2 && - CBlockIndex::IsSuperMajority(2, pindexPrev, Params().RejectBlockOutdatedMajority())) - { - return state.Invalid(error("%s : rejected nVersion=1 block", __func__), - REJECT_OBSOLETE, "bad-version"); - } } + if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + return false; + if (pindex == NULL) pindex = AddToBlockIndex(block); @@ -2415,7 +2459,7 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, return true; } - if (!CheckBlock(block, state)) { + if ((!CheckBlock(block, state)) || !ContextualCheckBlock(block, state, pindex->pprev)) { if (state.IsInvalid() && !state.CorruptionPossible()) { pindex->nStatus |= BLOCK_FAILED_VALID; } @@ -2424,27 +2468,6 @@ bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex** ppindex, int nHeight = pindex->nHeight; - // Check that all transactions are finalized - BOOST_FOREACH(const CTransaction& tx, block.vtx) - if (!IsFinalTx(tx, nHeight, block.GetBlockTime())) { - pindex->nStatus |= BLOCK_FAILED_VALID; - return state.DoS(10, error("AcceptBlock() : contains a non-final transaction"), - REJECT_INVALID, "bad-txns-nonfinal"); - } - - // Enforce block.nVersion=2 rule that the coinbase starts with serialized block height - // if 750 of the last 1,000 blocks are version 2 or greater (51/100 if testnet): - if (block.nVersion >= 2 && - CBlockIndex::IsSuperMajority(2, pindex->pprev, Params().EnforceBlockUpgradeMajority())) - { - CScript expect = CScript() << nHeight; - if (block.vtx[0].vin[0].scriptSig.size() < expect.size() || - !std::equal(expect.begin(), expect.end(), block.vtx[0].vin[0].scriptSig.begin())) { - pindex->nStatus |= BLOCK_FAILED_VALID; - return state.DoS(100, error("AcceptBlock() : block height mismatch in coinbase"), REJECT_INVALID, "bad-cb-height"); - } - } - // Write block to history file try { unsigned int nBlockSize = ::GetSerializeSize(block, SER_DISK, CLIENT_VERSION); @@ -2555,6 +2578,30 @@ bool ProcessNewBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDis return true; } +bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex * const pindexPrev, bool fCheckPOW, bool fCheckMerkleRoot) +{ + AssertLockHeld(cs_main); + assert(pindexPrev == chainActive.Tip()); + + CCoinsViewCache viewNew(pcoinsTip); + CBlockIndex indexDummy(block); + indexDummy.pprev = pindexPrev; + indexDummy.nHeight = pindexPrev->nHeight + 1; + + // NOTE: CheckBlockHeader is called by CheckBlock + if (!ContextualCheckBlockHeader(block, state, pindexPrev)) + return false; + if (!CheckBlock(block, state, fCheckPOW, fCheckMerkleRoot)) + return false; + if (!ContextualCheckBlock(block, state, pindexPrev)) + return false; + if (!ConnectBlock(block, state, &indexDummy, viewNew, true)) + return false; + assert(state.IsValid()); + + return true; +} + @@ -2811,7 +2858,7 @@ bool static LoadBlockIndexDB() BOOST_FOREACH(const PAIRTYPE(int, CBlockIndex*)& item, vSortedByHeight) { CBlockIndex* pindex = item.second; - pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + pindex->GetBlockWork(); + pindex->nChainWork = (pindex->pprev ? pindex->pprev->nChainWork : 0) + GetBlockProof(*pindex); if (pindex->nStatus & BLOCK_HAVE_DATA) { if (pindex->pprev) { if (pindex->pprev->nChainTx) { @@ -3216,12 +3263,12 @@ string GetWarnings(string strFor) string strStatusBar; string strRPC; - if (GetBoolArg("-testsafemode", false)) - strRPC = "test"; - if (!CLIENT_VERSION_IS_RELEASE) strStatusBar = _("This is a pre-release test build - use at your own risk - do not use for mining or merchant applications"); + if (GetBoolArg("-testsafemode", false)) + strStatusBar = strRPC = "testsafemode enabled"; + // Misc warnings like out of disk space and clock is wrong if (strMiscWarning != "") { diff --git a/src/main.h b/src/main.h index 1bb0919817..b49f0a06eb 100644 --- a/src/main.h +++ b/src/main.h @@ -457,12 +457,19 @@ bool ReadBlockFromDisk(CBlock& block, const CBlockIndex* pindex); bool DisconnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool* pfClean = NULL); // Apply the effects of this block (with given index) on the UTXO set represented by coins -bool ConnectBlock(CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); +bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pindex, CCoinsViewCache& coins, bool fJustCheck = false); // Context-independent validity checks bool CheckBlockHeader(const CBlockHeader& block, CValidationState& state, bool fCheckPOW = true); bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW = true, bool fCheckMerkleRoot = true); +// Context-dependent validity checks +bool ContextualCheckBlockHeader(const CBlockHeader& block, CValidationState& state, CBlockIndex *pindexPrev); +bool ContextualCheckBlock(const CBlock& block, CValidationState& state, CBlockIndex *pindexPrev); + +// Check a block is completely valid from start to finish (only works on top of our current best block, with cs_main held) +bool TestBlockValidity(CValidationState &state, const CBlock& block, CBlockIndex *pindexPrev, bool fCheckPOW = true, bool fCheckMerkleRoot = true); + // Store block on disk // if dbp is provided, the file is known to already reside on disk bool AcceptBlock(CBlock& block, CValidationState& state, CBlockIndex **pindex, CDiskBlockPos* dbp = NULL); diff --git a/src/miner.cpp b/src/miner.cpp index b5bfa9c7be..660173f35b 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -12,6 +12,7 @@ #include "main.h" #include "net.h" #include "pow.h" +#include "timedata.h" #include "util.h" #include "utilmoneystr.h" #ifdef ENABLE_WALLET @@ -78,6 +79,15 @@ public: } }; +void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) +{ + pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); + + // Updating time can change work required on testnet: + if (Params().AllowMinDifficultyBlocks()) + pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); +} + CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { // Create new block @@ -124,6 +134,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) { LOCK2(cs_main, mempool.cs); CBlockIndex* pindexPrev = chainActive.Tip(); + const int nHeight = pindexPrev->nHeight + 1; CCoinsViewCache view(pcoinsTip); // Priority order to process transactions @@ -138,7 +149,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) mi != mempool.mapTx.end(); ++mi) { const CTransaction& tx = mi->second.GetTx(); - if (tx.IsCoinBase() || !IsFinalTx(tx, pindexPrev->nHeight + 1)) + if (tx.IsCoinBase() || !IsFinalTx(tx, nHeight)) continue; COrphan* porphan = NULL; @@ -181,7 +192,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) CAmount nValueIn = coins->vout[txin.prevout.n].nValue; nTotalIn += nValueIn; - int nConf = pindexPrev->nHeight - coins->nHeight + 1; + int nConf = nHeight - coins->nHeight; dPriority += (double)nValueIn * nConf; } @@ -269,7 +280,7 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) continue; CTxUndo txundo; - UpdateCoins(tx, state, view, txundo, pindexPrev->nHeight+1); + UpdateCoins(tx, state, view, txundo, nHeight); // Added pblock->vtx.push_back(tx); @@ -309,8 +320,8 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) LogPrintf("CreateNewBlock(): total size %u\n", nBlockSize); // Compute final coinbase transaction. - txNew.vout[0].nValue = GetBlockValue(pindexPrev->nHeight+1, nFees); - txNew.vin[0].scriptSig = CScript() << OP_0 << OP_0; + txNew.vout[0].nValue = GetBlockValue(nHeight, nFees); + txNew.vin[0].scriptSig = CScript() << nHeight << OP_0; pblock->vtx[0] = txNew; pblocktemplate->vTxFees[0] = -nFees; @@ -321,13 +332,9 @@ CBlockTemplate* CreateNewBlock(const CScript& scriptPubKeyIn) pblock->nNonce = 0; pblocktemplate->vTxSigOps[0] = GetLegacySigOpCount(pblock->vtx[0]); - CBlockIndex indexDummy(*pblock); - indexDummy.pprev = pindexPrev; - indexDummy.nHeight = pindexPrev->nHeight + 1; - CCoinsViewCache viewNew(pcoinsTip); CValidationState state; - if (!ConnectBlock(*pblock, state, &indexDummy, viewNew, true)) - throw std::runtime_error("CreateNewBlock() : ConnectBlock failed"); + if (!TestBlockValidity(state, *pblock, pindexPrev, false, false)) + throw std::runtime_error("CreateNewBlock() : TestBlockValidity failed"); } return pblocktemplate.release(); diff --git a/src/miner.h b/src/miner.h index 1fa499dc5b..aede0e6d4b 100644 --- a/src/miner.h +++ b/src/miner.h @@ -9,6 +9,7 @@ #include <stdint.h> class CBlock; +class CBlockHeader; class CBlockIndex; class CReserveKey; class CScript; @@ -25,6 +26,7 @@ CBlockTemplate* CreateNewBlockWithKey(CReserveKey& reservekey); void IncrementExtraNonce(CBlock* pblock, CBlockIndex* pindexPrev, unsigned int& nExtraNonce); /** Check mined block */ bool CheckWork(CBlock* pblock, CWallet& wallet, CReserveKey& reservekey); +void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); extern double dHashesPerSec; extern int64_t nHPSTimerStart; diff --git a/src/pow.cpp b/src/pow.cpp index af7fc488ef..e07e7ff770 100644 --- a/src/pow.cpp +++ b/src/pow.cpp @@ -5,10 +5,9 @@ #include "pow.h" +#include "chain.h" #include "chainparams.h" #include "core/block.h" -#include "main.h" -#include "timedata.h" #include "uint256.h" #include "util.h" @@ -98,21 +97,12 @@ bool CheckProofOfWork(uint256 hash, unsigned int nBits) return true; } -void UpdateTime(CBlockHeader* pblock, const CBlockIndex* pindexPrev) -{ - pblock->nTime = std::max(pindexPrev->GetMedianTimePast()+1, GetAdjustedTime()); - - // Updating time can change work required on testnet: - if (Params().AllowMinDifficultyBlocks()) - pblock->nBits = GetNextWorkRequired(pindexPrev, pblock); -} - -uint256 GetProofIncrement(unsigned int nBits) +uint256 GetBlockProof(const CBlockIndex& block) { uint256 bnTarget; bool fNegative; bool fOverflow; - bnTarget.SetCompact(nBits, &fNegative, &fOverflow); + bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow); if (fNegative || fOverflow || bnTarget == 0) return 0; // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256 @@ -16,9 +16,6 @@ unsigned int GetNextWorkRequired(const CBlockIndex* pindexLast, const CBlockHead /** Check whether a block hash satisfies the proof-of-work requirement specified by nBits */ bool CheckProofOfWork(uint256 hash, unsigned int nBits); - -void UpdateTime(CBlockHeader* block, const CBlockIndex* pindexPrev); - -uint256 GetProofIncrement(unsigned int nBits); +uint256 GetBlockProof(const CBlockIndex& block); #endif // BITCOIN_POW_H diff --git a/src/qt/askpassphrasedialog.cpp b/src/qt/askpassphrasedialog.cpp index a448d5a9a0..fa9ac6b135 100644 --- a/src/qt/askpassphrasedialog.cpp +++ b/src/qt/askpassphrasedialog.cpp @@ -23,6 +23,10 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : { ui->setupUi(this); + ui->passEdit1->setMinimumSize(ui->passEdit1->sizeHint()); + ui->passEdit2->setMinimumSize(ui->passEdit2->sizeHint()); + ui->passEdit3->setMinimumSize(ui->passEdit3->sizeHint()); + ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE); ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE); @@ -35,9 +39,9 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : switch(mode) { case Encrypt: // Ask passphrase x2 + ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.")); ui->passLabel1->hide(); ui->passEdit1->hide(); - ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.")); setWindowTitle(tr("Encrypt wallet")); break; case Unlock: // Ask passphrase @@ -61,7 +65,6 @@ AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) : ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet.")); break; } - textChanged(); connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged())); diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 1073b6a472..548529865a 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -54,7 +54,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Delete all wallet transactions and only recover those parts of the " "blockchain through -rescan on startup"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Distributed under the MIT/X11 software license, see the accompanying file " +"Distributed under the MIT software license, see the accompanying file " "COPYING or <http://www.opensource.org/licenses/mit-license.php>."), QT_TRANSLATE_NOOP("bitcoin-core", "" "Enter regression test mode, which uses a special chain in which blocks can " @@ -103,6 +103,9 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Maintain a full transaction index, used by the getrawtransaction rpc call " "(default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" +"Maximum size of data in data carrier transactions we relay and mine " +"(default: %u)"), +QT_TRANSLATE_NOOP("bitcoin-core", "" "Number of seconds to keep misbehaving peers from reconnecting (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "Output debugging information (default: %u, supplying <category> is optional)"), @@ -115,8 +118,8 @@ QT_TRANSLATE_NOOP("bitcoin-core", "" "Set the number of script verification threads (%u to %d, 0 = auto, <0 = " "leave that many cores free, default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" -"Set the processor limit for when generation is on (-1 = unlimited, default: " -"%d)"), +"Set the number of threads for coin generation if enabled (-1 = all cores, " +"default: %d)"), QT_TRANSLATE_NOOP("bitcoin-core", "" "This is a pre-release test build - use at your own risk - do not use for " "mining or merchant applications"), @@ -250,6 +253,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Rescanning..."), QT_TRANSLATE_NOOP("bitcoin-core", "Run a thread to flush wallet periodically (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Run in the background as a daemon and accept commands"), QT_TRANSLATE_NOOP("bitcoin-core", "Send trace/debug info to console instead of debug.log file"), +QT_TRANSLATE_NOOP("bitcoin-core", "Send transactions as zero-fee transactions if possible (default: %u)"), QT_TRANSLATE_NOOP("bitcoin-core", "Server certificate file (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Server private key (default: %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Set database cache size in megabytes (%d to %d, default: %d)"), diff --git a/src/qt/forms/askpassphrasedialog.ui b/src/qt/forms/askpassphrasedialog.ui index bc4921455f..a2105ecd0a 100644 --- a/src/qt/forms/askpassphrasedialog.ui +++ b/src/qt/forms/askpassphrasedialog.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>598</width> - <height>198</height> + <height>222</height> </rect> </property> <property name="sizePolicy"> @@ -26,8 +26,14 @@ <string>Passphrase Dialog</string> </property> <layout class="QVBoxLayout" name="verticalLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> <item> <widget class="QLabel" name="warningLabel"> + <property name="text"> + <string notr="true">Placeholder text</string> + </property> <property name="textFormat"> <enum>Qt::RichText</enum> </property> @@ -38,6 +44,9 @@ </item> <item> <layout class="QFormLayout" name="formLayout"> + <property name="sizeConstraint"> + <enum>QLayout::SetMinimumSize</enum> + </property> <property name="fieldGrowthPolicy"> <enum>QFormLayout::AllNonFixedFieldsGrow</enum> </property> diff --git a/src/qt/forms/optionsdialog.ui b/src/qt/forms/optionsdialog.ui index 3446cf5c33..51156ade4f 100644 --- a/src/qt/forms/optionsdialog.ui +++ b/src/qt/forms/optionsdialog.ui @@ -209,10 +209,10 @@ <item> <widget class="QCheckBox" name="connectSocks"> <property name="toolTip"> - <string>Connect to the Bitcoin network through a SOCKS proxy.</string> + <string>Connect to the Bitcoin network through a SOCKS5 proxy.</string> </property> <property name="text"> - <string>&Connect through SOCKS proxy (default proxy):</string> + <string>&Connect through SOCKS5 proxy (default proxy):</string> </property> </widget> </item> diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h index a6ecfbcc82..09c79db2d9 100644 --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -189,7 +189,7 @@ namespace GUIUtil /* Format a CNodeCombinedStats.dPingTime into a user-readable string or display N/A, if 0*/ QString formatPingTime(double dPingTime); -#ifdef Q_OS_MAC +#if defined(Q_OS_MAC) && QT_VERSION >= 0x050000 // workaround for Qt OSX Bug: // https://bugreports.qt-project.org/browse/QTBUG-15631 // QProgressBar uses around 10% CPU even when app is in background diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index df285441e1..71c626be4b 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE TS> -<TS version="2.1" language="en"> +<TS version="2.0" language="en"> <context> <name>AddressBookPage</name> <message> @@ -150,7 +150,7 @@ <translation>Passphrase Dialog</translation> </message> <message> - <location line="+21"/> + <location line="+30"/> <source>Enter passphrase</source> <translation>Enter passphrase</translation> </message> @@ -165,7 +165,7 @@ <translation>Repeat new passphrase</translation> </message> <message> - <location filename="../askpassphrasedialog.cpp" line="+41"/> + <location filename="../askpassphrasedialog.cpp" line="+45"/> <source>Encrypt wallet</source> <translation>Encrypt wallet</translation> </message> @@ -200,7 +200,7 @@ <translation>Enter the old and new passphrase to the wallet.</translation> </message> <message> - <location line="+46"/> + <location line="+45"/> <source>Confirm wallet encryption</source> <translation>Confirm wallet encryption</translation> </message> @@ -232,12 +232,12 @@ <translation>Wallet encrypted</translation> </message> <message> - <location line="-135"/> + <location line="-136"/> <source>Enter the new passphrase to the wallet.<br/>Please use a passphrase of <b>ten or more random characters</b>, or <b>eight or more words</b>.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+79"/> + <location line="+80"/> <source>Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</source> <translation>Bitcoin will close now to finish the encryption process. Remember that encrypting your wallet cannot fully protect your bitcoins from being stolen by malware infecting your computer.</translation> </message> @@ -286,7 +286,7 @@ <context> <name>BitcoinGUI</name> <message> - <location filename="../bitcoingui.cpp" line="+309"/> + <location filename="../bitcoingui.cpp" line="+311"/> <source>Sign &message...</source> <translation>Sign &message...</translation> </message> @@ -296,7 +296,7 @@ <translation>Synchronizing with network...</translation> </message> <message> - <location line="-405"/> + <location line="-407"/> <source>&Overview</source> <translation>&Overview</translation> </message> @@ -321,7 +321,7 @@ <translation>Browse transaction history</translation> </message> <message> - <location line="+17"/> + <location line="+19"/> <source>E&xit</source> <translation>E&xit</translation> </message> @@ -392,12 +392,12 @@ <translation>Reindexing blocks on disk...</translation> </message> <message> - <location line="-403"/> + <location line="-405"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> <message> - <location line="+46"/> + <location line="+48"/> <source>Modify configuration options for Bitcoin</source> <translation>Modify configuration options for Bitcoin</translation> </message> @@ -432,7 +432,7 @@ <translation>Bitcoin</translation> </message> <message> - <location line="-636"/> + <location line="-638"/> <source>Wallet</source> <translation>Wallet</translation> </message> @@ -447,7 +447,7 @@ <translation>&Receive</translation> </message> <message> - <location line="+30"/> + <location line="+32"/> <source>Show information about Bitcoin Core</source> <translation type="unfinished"></translation> </message> @@ -497,7 +497,7 @@ <translation>Tabs toolbar</translation> </message> <message> - <location line="-295"/> + <location line="-297"/> <source>Bitcoin Core</source> <translation type="unfinished">Bitcoin Core</translation> </message> @@ -507,7 +507,7 @@ <translation type="unfinished"></translation> </message> <message> - <location line="+28"/> + <location line="+30"/> <source>&About Bitcoin Core</source> <translation type="unfinished"></translation> </message> @@ -672,7 +672,7 @@ Address: %4 <context> <name>ClientModel</name> <message> - <location filename="../clientmodel.cpp" line="+139"/> + <location filename="../clientmodel.cpp" line="+140"/> <source>Network Alert</source> <translation>Network Alert</translation> </message> @@ -681,7 +681,7 @@ Address: %4 <name>CoinControlDialog</name> <message> <location filename="../forms/coincontroldialog.ui" line="+14"/> - <source>Coin Control Address Selection</source> + <source>Coin Selection</source> <translation type="unfinished"></translation> </message> <message> @@ -735,19 +735,24 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+16"/> + <location line="+13"/> <source>List mode</source> <translation type="unfinished"></translation> </message> <message> - <location line="+53"/> + <location line="+56"/> <source>Amount</source> <translation type="unfinished">Amount</translation> </message> <message> - <location line="+10"/> - <source>Address</source> - <translation type="unfinished">Address</translation> + <location line="+5"/> + <source>Received with label</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+5"/> + <source>Received with address</source> + <translation type="unfinished"></translation> </message> <message> <location line="+5"/> @@ -770,7 +775,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location filename="../coincontroldialog.cpp" line="+43"/> + <location filename="../coincontroldialog.cpp" line="+44"/> <source>Copy address</source> <translation type="unfinished">Copy address</translation> </message> @@ -836,17 +841,17 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+333"/> + <location line="+347"/> <source>highest</source> <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> + <location line="+1"/> <source>higher</source> <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> + <location line="+1"/> <source>high</source> <translation type="unfinished"></translation> </message> @@ -856,18 +861,17 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> - <location line="+12"/> + <location line="+1"/> <source>medium</source> <translation type="unfinished"></translation> </message> <message> - <location line="-11"/> + <location line="+1"/> <source>low-medium</source> <translation type="unfinished"></translation> </message> <message> - <location line="+0"/> + <location line="+1"/> <source>low</source> <translation type="unfinished"></translation> </message> @@ -877,7 +881,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+1"/> <source>lowest</source> <translation type="unfinished"></translation> </message> @@ -892,12 +896,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+162"/> + <location line="+165"/> <source>Can vary +/- %1 satoshi(s) per input.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-28"/> + <location line="-32"/> <source>yes</source> <translation type="unfinished"></translation> </message> @@ -938,7 +942,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+50"/> + <location line="+55"/> <location line="+61"/> <source>(no label)</source> <translation type="unfinished">(no label)</translation> @@ -1224,17 +1228,7 @@ Address: %4 <translation>&Main</translation> </message> <message> - <location line="+116"/> - <source>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</source> - <translation>Optional transaction fee per kB that helps make sure your transactions are processed quickly. Most transactions are 1 kB.</translation> - </message> - <message> - <location line="+15"/> - <source>Pay transaction &fee</source> - <translation>Pay transaction &fee</translation> - </message> - <message> - <location line="-125"/> + <location line="+6"/> <source>Automatically start Bitcoin after logging in to the system.</source> <translation>Automatically start Bitcoin after logging in to the system.</translation> </message> @@ -1259,7 +1253,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+160"/> + <location line="+114"/> <source>Accept connections from outside</source> <translation type="unfinished"></translation> </message> @@ -1269,17 +1263,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+7"/> - <source>Connect to the Bitcoin network through a SOCKS proxy.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+3"/> - <source>&Connect through SOCKS proxy (default proxy):</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+34"/> + <location line="+44"/> <source>IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <translation type="unfinished"></translation> </message> @@ -1315,7 +1299,7 @@ Address: %4 <translation>&Network</translation> </message> <message> - <location line="-131"/> + <location line="-85"/> <source>(0 = auto, <0 = leave that many cores free)</source> <translation type="unfinished"></translation> </message> @@ -1325,7 +1309,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+65"/> + <location line="+6"/> <source>Expert</source> <translation type="unfinished"></translation> </message> @@ -1345,7 +1329,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> + <location line="+30"/> <source>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <translation>Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</translation> </message> @@ -1355,7 +1339,17 @@ Address: %4 <translation>Map port using &UPnP</translation> </message> <message> - <location line="+29"/> + <location line="+17"/> + <source>Connect to the Bitcoin network through a SOCKS5 proxy.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>&Connect through SOCKS5 proxy (default proxy):</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+9"/> <source>Proxy &IP:</source> <translation>Proxy &IP:</translation> </message> @@ -1420,12 +1414,12 @@ Address: %4 <translation>Choose the default subdivision unit to show in the interface and when sending coins.</translation> </message> <message> - <location line="-240"/> + <location line="-253"/> <source>Whether to show coin control features or not.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+402"/> + <location line="+415"/> <source>&OK</source> <translation>&OK</translation> </message> @@ -1435,17 +1429,17 @@ Address: %4 <translation>&Cancel</translation> </message> <message> - <location filename="../optionsdialog.cpp" line="+71"/> + <location filename="../optionsdialog.cpp" line="+76"/> <source>default</source> <translation>default</translation> </message> <message> - <location line="+63"/> + <location line="+60"/> <source>none</source> <translation type="unfinished"></translation> </message> <message> - <location line="+82"/> + <location line="+76"/> <source>Confirm options reset</source> <translation>Confirm options reset</translation> </message> @@ -1466,7 +1460,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+34"/> + <location line="+25"/> <source>The supplied proxy address is invalid.</source> <translation>The supplied proxy address is invalid.</translation> </message> @@ -2268,7 +2262,7 @@ Address: %4 <context> <name>RecentRequestsTableModel</name> <message> - <location filename="../recentrequeststablemodel.cpp" line="+26"/> + <location filename="../recentrequeststablemodel.cpp" line="+28"/> <source>Date</source> <translation type="unfinished">Date</translation> </message> @@ -2307,7 +2301,7 @@ Address: %4 <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+447"/> + <location filename="../sendcoinsdialog.cpp" line="+529"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -2377,7 +2371,98 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+164"/> + <location line="+206"/> + <source>Transaction Fee:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+14"/> + <source>Choose...</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>collapse fee-settings</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>Minimize</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+78"/> + <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>per kilobyte</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+13"/> + <source>If the custom fee is set to 1000 satoshis and the transaction is only 250 bytes, then "per kilobyte" only pays 250 satoshis in fee, while "total at least" pays 1000 satoshis. For transactions bigger than a kilobyte both pay by kilobyte.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>total at least</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <location line="+13"/> + <source>Paying only the minimum fee is just fine as long as there is less transaction volume than space in the blocks. But be aware that this can end up in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> + <source>(read the tooltip)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+29"/> + <source>Recommended:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+30"/> + <source>Custom:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+52"/> + <source>(Smart fee not initialized yet. This usually takes a few blocks...)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+29"/> + <source>Confirmation time:</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+60"/> + <source>normal</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+20"/> + <source>fast</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+38"/> + <source>Send as zero-fee transaction if possible</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> + <source>(confirmation may take longer)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+110"/> <source>Send to multiple recipients at once</source> <translation>Send to multiple recipients at once</translation> </message> @@ -2392,12 +2477,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-274"/> + <location line="-858"/> <source>Dust:</source> <translation type="unfinished"></translation> </message> <message> - <location line="+277"/> + <location line="+861"/> <source>Clear &All</source> <translation>Clear &All</translation> </message> @@ -2417,12 +2502,12 @@ Address: %4 <translation>S&end</translation> </message> <message> - <location filename="../sendcoinsdialog.cpp" line="-215"/> + <location filename="../sendcoinsdialog.cpp" line="-221"/> <source>Confirm send coins</source> <translation>Confirm send coins</translation> </message> <message> - <location line="-74"/> + <location line="-77"/> <location line="+5"/> <location line="+5"/> <location line="+4"/> @@ -2430,7 +2515,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-122"/> + <location line="-192"/> <source>Copy quantity</source> <translation type="unfinished"></translation> </message> @@ -2465,7 +2550,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+171"/> + <location line="+244"/> <source>Total Amount %1 (= %2)</source> <translation type="unfinished"></translation> </message> @@ -2475,7 +2560,7 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+189"/> + <location line="+192"/> <source>The recipient address is not valid, please recheck.</source> <translation>The recipient address is not valid, please recheck.</translation> </message> @@ -2510,7 +2595,22 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="+113"/> + <location line="+4"/> + <source>A fee higher than %1 is considered an insanely high fee.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+87"/> + <source>Pay only the minimum fee of %1</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+22"/> + <source>Estimated to begin confirmation within %1 block(s).</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+107"/> <source>Warning: Invalid Bitcoin address</source> <translation type="unfinished"></translation> </message> @@ -2525,12 +2625,12 @@ Address: %4 <translation type="unfinished"></translation> </message> <message> - <location line="-504"/> + <location line="-687"/> <source>Copy dust</source> <translation type="unfinished"></translation> </message> <message> - <location line="+151"/> + <location line="+221"/> <source>Are you sure you want to send?</source> <translation type="unfinished"></translation> </message> @@ -3087,7 +3187,7 @@ Address: %4 <context> <name>TransactionTableModel</name> <message> - <location filename="../transactiontablemodel.cpp" line="+235"/> + <location filename="../transactiontablemodel.cpp" line="+229"/> <source>Date</source> <translation>Date</translation> </message> @@ -3102,7 +3202,7 @@ Address: %4 <translation>Address</translation> </message> <message> - <location line="+76"/> + <location line="+79"/> <source>Immature (%1 confirmations, will be available after %2)</source> <translation type="unfinished"></translation> </message> @@ -3418,7 +3518,7 @@ Address: %4 <context> <name>WalletModel</name> <message> - <location filename="../walletmodel.cpp" line="+280"/> + <location filename="../walletmodel.cpp" line="+276"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -3436,7 +3536,7 @@ Address: %4 <translation>Export the data in the current tab to a file</translation> </message> <message> - <location line="+184"/> + <location line="+187"/> <source>Backup Wallet</source> <translation>Backup Wallet</translation> </message> @@ -3469,27 +3569,27 @@ Address: %4 <context> <name>bitcoin-core</name> <message> - <location filename="../bitcoinstrings.cpp" line="+236"/> + <location filename="../bitcoinstrings.cpp" line="+239"/> <source>Options:</source> <translation>Options:</translation> </message> <message> - <location line="+30"/> + <location line="+31"/> <source>Specify data directory</source> <translation>Specify data directory</translation> </message> <message> - <location line="-90"/> + <location line="-91"/> <source>Connect to a node to retrieve peer addresses, and disconnect</source> <translation>Connect to a node to retrieve peer addresses, and disconnect</translation> </message> <message> - <location line="+93"/> + <location line="+94"/> <source>Specify your own public address</source> <translation>Specify your own public address</translation> </message> <message> - <location line="-108"/> + <location line="-109"/> <source>Accept command line and JSON-RPC commands</source> <translation>Accept command line and JSON-RPC commands</translation> </message> @@ -3499,17 +3599,17 @@ Address: %4 <translation>Run in the background as a daemon and accept commands</translation> </message> <message> - <location line="+35"/> + <location line="+36"/> <source>Use the test network</source> <translation>Use the test network</translation> </message> <message> - <location line="-124"/> + <location line="-125"/> <source>Accept connections from outside (default: 1 if no -proxy or -connect)</source> <translation>Accept connections from outside (default: 1 if no -proxy or -connect)</translation> </message> <message> - <location line="-150"/> + <location line="-153"/> <source>%s, you must set a rpcpassword in the configuration file: %s It is recommended you use the following random password: @@ -3544,7 +3644,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> + <location line="+3"/> + <source>Distributed under the MIT software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+3"/> <source>Enter regression test mode, which uses a special chain in which blocks can be solved instantly.</source> <translation type="unfinished"></translation> </message> @@ -3569,7 +3674,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+17"/> + <location line="+20"/> <source>Set the number of script verification threads (%u to %d, 0 = auto, <0 = leave that many cores free, default: %d)</source> <translation type="unfinished"></translation> </message> @@ -3744,7 +3849,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Rebuild block chain index from current blk000??.dat files</translation> </message> <message> - <location line="+10"/> + <location line="+11"/> <source>Set database cache size in megabytes (%d to %d, default: %d)</source> <translation type="unfinished"></translation> </message> @@ -3794,12 +3899,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>You need to rebuild the database using -reindex to change -txindex</translation> </message> <message> - <location line="-91"/> + <location line="-92"/> <source>Imports blocks from external blk000??.dat file</source> <translation>Imports blocks from external blk000??.dat file</translation> </message> <message> - <location line="-179"/> + <location line="-182"/> <source>Allow JSON-RPC connections from specified source. Valid for <ip> are a single IP (e.g. 1.2.3.4), a network/netmask (e.g. 1.2.3.4/255.255.255.0) or a network/CIDR (e.g. 1.2.3.4/24). This option can be specified multiple times</source> <translation type="unfinished"></translation> </message> @@ -3834,12 +3939,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+6"/> - <source>Distributed under the MIT/X11 software license, see the accompanying file COPYING or <http://www.opensource.org/licenses/mit-license.php>.</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+6"/> + <location line="+12"/> <source>Error: Listening for incoming connections failed (listen returned error %s)</source> <translation type="unfinished"></translation> </message> @@ -3864,7 +3964,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+23"/> + <location line="+19"/> + <source>Maximum size of data in data carrier transactions we relay and mine (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+7"/> <source>Query for peer addresses via DNS lookup, if low on addresses (default: 1 unless -connect)</source> <translation type="unfinished"></translation> </message> @@ -3874,7 +3979,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+11"/> + <location line="+5"/> + <source>Set the number of threads for coin generation if enabled (-1 = all cores, default: %d)</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+6"/> <source>This product includes software developed by the OpenSSL Project for use in the OpenSSL Toolkit <https://www.openssl.org/> and cryptographic software written by Eric Young and UPnP software written by Thomas Bernard.</source> <translation type="unfinished"></translation> </message> @@ -4004,6 +4114,11 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Send trace/debug info to console instead of debug.log file</translation> </message> <message> + <location line="+1"/> + <source>Send transactions as zero-fee transactions if possible (default: %u)</source> + <translation type="unfinished"></translation> + </message> + <message> <location line="+9"/> <source>Show all debugging options (usage: --help -help-debug)</source> <translation type="unfinished"></translation> @@ -4094,27 +4209,27 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>wallet.dat corrupt, salvage failed</translation> </message> <message> - <location line="-63"/> + <location line="-64"/> <source>Password for JSON-RPC connections</source> <translation>Password for JSON-RPC connections</translation> </message> <message> - <location line="-157"/> + <location line="-160"/> <source>Execute command when the best block changes (%s in cmd is replaced by block hash)</source> <translation>Execute command when the best block changes (%s in cmd is replaced by block hash)</translation> </message> <message> - <location line="+202"/> + <location line="+206"/> <source>Upgrade wallet to latest format</source> <translation>Upgrade wallet to latest format</translation> </message> <message> - <location line="-34"/> + <location line="-35"/> <source>Rescan the block chain for missing wallet transactions</source> <translation>Rescan the block chain for missing wallet transactions</translation> </message> <message> - <location line="+35"/> + <location line="+36"/> <source>Use OpenSSL (https) for JSON-RPC connections</source> <translation>Use OpenSSL (https) for JSON-RPC connections</translation> </message> @@ -4124,7 +4239,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>This help message</translation> </message> <message> - <location line="-107"/> + <location line="-108"/> <source>Allow DNS lookups for -addnode, -seednode and -connect</source> <translation>Allow DNS lookups for -addnode, -seednode and -connect</translation> </message> @@ -4139,7 +4254,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Error loading wallet.dat: Wallet corrupted</translation> </message> <message> - <location line="-167"/> + <location line="-170"/> <source>(1 = keep tx meta data e.g. account owner and payment request information, 2 = drop tx meta data)</source> <translation type="unfinished"></translation> </message> @@ -4169,7 +4284,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+6"/> <source>Number of seconds to keep misbehaving peers from reconnecting (default: %u)</source> <translation type="unfinished"></translation> </message> @@ -4179,12 +4294,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+10"/> - <source>Set the processor limit for when generation is on (-1 = unlimited, default: %d)</source> - <translation type="unfinished"></translation> - </message> - <message> - <location line="+13"/> + <location line="+23"/> <source>Use separate SOCKS5 proxy to reach peers via Tor hidden services (default: %s)</source> <translation type="unfinished"></translation> </message> @@ -4299,7 +4409,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation type="unfinished"></translation> </message> <message> - <location line="+3"/> + <location line="+4"/> <source>Server certificate file (default: %s)</source> <translation type="unfinished"></translation> </message> @@ -4364,7 +4474,7 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Unknown network specified in -onlynet: '%s'</translation> </message> <message> - <location line="-111"/> + <location line="-112"/> <source>Cannot resolve -bind address: '%s'</source> <translation>Cannot resolve -bind address: '%s'</translation> </message> @@ -4424,12 +4534,12 @@ for example: alertnotify=echo %%s | mail -s "Bitcoin Alert" admin@foo. <translation>Done loading</translation> </message> <message> - <location line="+90"/> + <location line="+91"/> <source>To use the %s option</source> <translation>To use the %s option</translation> </message> <message> - <location line="-82"/> + <location line="-83"/> <source>Error</source> <translation>Error</translation> </message> diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index ff39829b95..813f29f53a 100644 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -12,12 +12,12 @@ #include "guiutil.h" #include "optionsmodel.h" #include "sendcoinsentry.h" -#include "wallet.h" #include "walletmodel.h" #include "base58.h" #include "coincontrol.h" #include "ui_interface.h" +#include "wallet.h" #include <QMessageBox> #include <QScrollBar> diff --git a/src/rest.cpp b/src/rest.cpp index 9a8793a517..122b361719 100644 --- a/src/rest.cpp +++ b/src/rest.cpp @@ -1,17 +1,18 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2012 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include <boost/algorithm/string.hpp> -#include "rpcserver.h" -#include "streams.h" -#include "utilstrencodings.h" #include "core/block.h" #include "core/transaction.h" -#include "version.h" #include "main.h" +#include "rpcserver.h" +#include "streams.h" #include "sync.h" +#include "utilstrencodings.h" +#include "version.h" + +#include <boost/algorithm/string.hpp> using namespace std; using namespace json_spirit; @@ -163,7 +164,7 @@ static bool rest_tx(AcceptedConnection *conn, string strJSON = write_string(Value(objTx), false) + "\n"; conn->stream() << HTTPReply(HTTP_OK, strJSON, fRun) << std::flush; return true; - } + } } // not reached @@ -203,4 +204,3 @@ bool HTTPReq_REST(AcceptedConnection *conn, conn->stream() << HTTPError(HTTP_NOT_FOUND, false) << std::flush; return false; } - diff --git a/src/rpcblockchain.cpp b/src/rpcblockchain.cpp index a7cd63bd95..7919fb1a0c 100644 --- a/src/rpcblockchain.cpp +++ b/src/rpcblockchain.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "checkpoints.h" @@ -468,7 +468,7 @@ Value getblockchaininfo(const Array& params, bool fHelp) return obj; } -/* Comparison function for sorting the getchaintips heads. */ +/** Comparison function for sorting the getchaintips heads. */ struct CompareBlocksByHeight { bool operator()(const CBlockIndex* a, const CBlockIndex* b) const diff --git a/src/rpcclient.cpp b/src/rpcclient.cpp index 7a1f1918f6..03ce9acbbf 100644 --- a/src/rpcclient.cpp +++ b/src/rpcclient.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcclient.h" @@ -18,8 +18,8 @@ using namespace json_spirit; class CRPCConvertParam { public: - std::string methodName; // method whose params want conversion - int paramIdx; // 0-based idx of param to convert + std::string methodName; //! method whose params want conversion + int paramIdx; //! 0-based idx of param to convert }; static const CRPCConvertParam vRPCConvertParams[] = @@ -116,7 +116,7 @@ CRPCConvertTable::CRPCConvertTable() static CRPCConvertTable rpcCvtTable; -// Convert strings to command-specific RPC representation +/** Convert strings to command-specific RPC representation */ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::string> &strParams) { Array params; diff --git a/src/rpcclient.h b/src/rpcclient.h index cd11f177e8..a91c2eb033 100644 --- a/src/rpcclient.h +++ b/src/rpcclient.h @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_RPCCLIENT_H diff --git a/src/rpcdump.cpp b/src/rpcdump.cpp index 9da0a7d091..8b95373cff 100644 --- a/src/rpcdump.cpp +++ b/src/rpcdump.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" @@ -112,6 +112,7 @@ Value importprivkey(const Array& params, bool fHelp) if (!key.IsValid()) throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Private key outside allowed range"); CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); CKeyID vchAddress = pubkey.GetID(); { pwalletMain->MarkDirty(); @@ -253,6 +254,7 @@ Value importwallet(const Array& params, bool fHelp) continue; CKey key = vchSecret.GetKey(); CPubKey pubkey = key.GetPubKey(); + assert(key.VerifyPubKey(pubkey)); CKeyID keyid = pubkey.GetID(); if (pwalletMain->HaveKey(keyid)) { LogPrintf("Skipping import of %s (key already present)\n", CBitcoinAddress(keyid).ToString()); diff --git a/src/rpcmining.cpp b/src/rpcmining.cpp index 2bde02c0a1..837a7593b6 100644 --- a/src/rpcmining.cpp +++ b/src/rpcmining.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "amount.h" @@ -28,9 +28,11 @@ using namespace json_spirit; using namespace std; -// Return average network hashes per second based on the last 'lookup' blocks, -// or from the last difficulty change if 'lookup' is nonpositive. -// If 'height' is nonnegative, compute the estimate at the time when a given block was found. +/** + * Return average network hashes per second based on the last 'lookup' blocks, + * or from the last difficulty change if 'lookup' is nonpositive. + * If 'height' is nonnegative, compute the estimate at the time when a given block was found. + */ Value GetNetworkHashPS(int lookup, int height) { CBlockIndex *pb = chainActive.Tip(); @@ -297,6 +299,25 @@ Value prioritisetransaction(const Array& params, bool fHelp) } +// NOTE: Assumes a conclusive result; if result is inconclusive, it must be handled by caller +static Value BIP22ValidationResult(const CValidationState& state) +{ + if (state.IsValid()) + return Value::null; + + std::string strRejectReason = state.GetRejectReason(); + if (state.IsError()) + throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason); + if (state.IsInvalid()) + { + if (strRejectReason.empty()) + return "rejected"; + return strRejectReason; + } + // Should be impossible + return "valid?"; +} + Value getblocktemplate(const Array& params, bool fHelp) { if (fHelp || params.size() > 1) @@ -374,6 +395,36 @@ Value getblocktemplate(const Array& params, bool fHelp) else throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode"); lpval = find_value(oparam, "longpollid"); + + if (strMode == "proposal") + { + const Value& dataval = find_value(oparam, "data"); + if (dataval.type() != str_type) + throw JSONRPCError(RPC_TYPE_ERROR, "Missing data String key for proposal"); + + CBlock block; + if (!DecodeHexBlk(block, dataval.get_str())) + throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + + uint256 hash = block.GetHash(); + BlockMap::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) { + CBlockIndex *pindex = mi->second; + if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) + return "duplicate"; + if (pindex->nStatus & BLOCK_FAILED_MASK) + return "duplicate-invalid"; + return "duplicate-inconclusive"; + } + + CBlockIndex* const pindexPrev = chainActive.Tip(); + // TestBlockValidity only supports blocks built on the current Tip + if (block.hashPrevBlock != pindexPrev->GetBlockHash()) + return "inconclusive-not-best-prevblk"; + CValidationState state; + TestBlockValidity(state, block, pindexPrev, false, true); + return BIP22ValidationResult(state); + } } if (strMode != "template") @@ -476,6 +527,8 @@ Value getblocktemplate(const Array& params, bool fHelp) UpdateTime(pblock, pindexPrev); pblock->nNonce = 0; + static const Array aCaps = boost::assign::list_of("proposal"); + Array transactions; map<uint256, int64_t> setTxIndex; int i = 0; @@ -522,6 +575,7 @@ Value getblocktemplate(const Array& params, bool fHelp) } Object result; + result.push_back(Pair("capabilities", aCaps)); result.push_back(Pair("version", pblock->nVersion)); result.push_back(Pair("previousblockhash", pblock->hashPrevBlock.GetHex())); result.push_back(Pair("transactions", transactions)); @@ -580,41 +634,39 @@ Value submitblock(const Array& params, bool fHelp) + HelpExampleRpc("submitblock", "\"mydata\"") ); - vector<unsigned char> blockData(ParseHex(params[0].get_str())); - CDataStream ssBlock(blockData, SER_NETWORK, PROTOCOL_VERSION); - CBlock pblock; - try { - ssBlock >> pblock; - } - catch (const std::exception &) { + CBlock block; + if (!DecodeHexBlk(block, params[0].get_str())) throw JSONRPCError(RPC_DESERIALIZATION_ERROR, "Block decode failed"); + + uint256 hash = block.GetHash(); + BlockMap::iterator mi = mapBlockIndex.find(hash); + if (mi != mapBlockIndex.end()) { + CBlockIndex *pindex = mi->second; + if (pindex->IsValid(BLOCK_VALID_SCRIPTS)) + return "duplicate"; + if (pindex->nStatus & BLOCK_FAILED_MASK) + return "duplicate-invalid"; + // Otherwise, we might only have the header - process the block before returning } CValidationState state; - submitblock_StateCatcher sc(pblock.GetHash()); + submitblock_StateCatcher sc(block.GetHash()); RegisterValidationInterface(&sc); - bool fAccepted = ProcessNewBlock(state, NULL, &pblock); + bool fAccepted = ProcessNewBlock(state, NULL, &block); UnregisterValidationInterface(&sc); + if (mi != mapBlockIndex.end()) + { + if (fAccepted && !sc.found) + return "duplicate-inconclusive"; + return "duplicate"; + } if (fAccepted) { if (!sc.found) return "inconclusive"; state = sc.state; } - if (state.IsError()) - { - std::string strRejectReason = state.GetRejectReason(); - throw JSONRPCError(RPC_VERIFY_ERROR, strRejectReason); - } - if (state.IsInvalid()) - { - std::string strRejectReason = state.GetRejectReason(); - if (strRejectReason.empty()) - return "rejected"; - return strRejectReason; - } - - return Value::null; + return BIP22ValidationResult(state); } Value estimatefee(const Array& params, bool fHelp) diff --git a/src/rpcmisc.cpp b/src/rpcmisc.cpp index 31eaae6162..90b9c99caa 100644 --- a/src/rpcmisc.cpp +++ b/src/rpcmisc.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" @@ -30,7 +30,7 @@ using namespace std; /** * @note Do not add or change anything in the information returned by this - * method. `getinfo` exists for backwards-compatibilty only. It combines + * method. `getinfo` exists for backwards-compatibility only. It combines * information from wildly different sources in the program, which is a mess, * and is thus planned to be deprecated eventually. * @@ -198,9 +198,9 @@ Value validateaddress(const Array& params, bool fHelp) return ret; } -// -// Used by addmultisigaddress / createmultisig: -// +/** + * Used by addmultisigaddress / createmultisig: + */ CScript _createmultisig_redeemScript(const Array& params) { int nRequired = params[0].get_int(); diff --git a/src/rpcnet.cpp b/src/rpcnet.cpp index 46b5f3d7ad..6ddbd62fca 100644 --- a/src/rpcnet.cpp +++ b/src/rpcnet.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcserver.h" diff --git a/src/rpcprotocol.cpp b/src/rpcprotocol.cpp index c2ce73106f..2f7c491f3d 100644 --- a/src/rpcprotocol.cpp +++ b/src/rpcprotocol.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "rpcprotocol.h" @@ -30,15 +30,15 @@ using namespace boost; using namespace boost::asio; using namespace json_spirit; -// Number of bytes to allocate and read at most at once in post data +//! Number of bytes to allocate and read at most at once in post data const size_t POST_READ_SIZE = 256 * 1024; -// -// HTTP protocol -// -// This ain't Apache. We're just using HTTP header for the length field -// and to be compatible with other JSON-RPC implementations. -// +/** + * HTTP protocol + * + * This ain't Apache. We're just using HTTP header for the length field + * and to be compatible with other JSON-RPC implementations. + */ string HTTPPost(const string& strMsg, const map<string,string>& mapRequestHeaders) { @@ -246,15 +246,15 @@ int ReadHTTPMessage(std::basic_istream<char>& stream, map<string, return HTTP_OK; } -// -// JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, -// but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were -// unspecified (HTTP errors and contents of 'error'). -// -// 1.0 spec: http://json-rpc.org/wiki/specification -// 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html -// http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx -// +/** + * JSON-RPC protocol. Bitcoin speaks version 1.0 for maximum compatibility, + * but uses JSON-RPC 1.1/2.0 standards for parts of the 1.0 standard that were + * unspecified (HTTP errors and contents of 'error'). + * + * 1.0 spec: http://json-rpc.org/wiki/specification + * 1.2 spec: http://jsonrpc.org/historical/json-rpc-over-http.html + * http://www.codeproject.com/KB/recipes/JSON_Spirit.aspx + */ string JSONRPCRequest(const string& strMethod, const Array& params, const Value& id) { diff --git a/src/rpcprotocol.h b/src/rpcprotocol.h index f0d0f3445c..a321338176 100644 --- a/src/rpcprotocol.h +++ b/src/rpcprotocol.h @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_RPCPROTOCOL_H @@ -19,7 +19,7 @@ #include "json/json_spirit_utils.h" #include "json/json_spirit_writer_template.h" -// HTTP status codes +//! HTTP status codes enum HTTPStatusCode { HTTP_OK = 200, @@ -30,56 +30,56 @@ enum HTTPStatusCode HTTP_INTERNAL_SERVER_ERROR = 500, }; -// Bitcoin RPC error codes +//! Bitcoin RPC error codes enum RPCErrorCode { - // Standard JSON-RPC 2.0 errors + //! Standard JSON-RPC 2.0 errors RPC_INVALID_REQUEST = -32600, RPC_METHOD_NOT_FOUND = -32601, RPC_INVALID_PARAMS = -32602, RPC_INTERNAL_ERROR = -32603, RPC_PARSE_ERROR = -32700, - // General application defined errors - RPC_MISC_ERROR = -1, // std::exception thrown in command handling - RPC_FORBIDDEN_BY_SAFE_MODE = -2, // Server is in safe mode, and command is not allowed in safe mode - RPC_TYPE_ERROR = -3, // Unexpected type was passed as parameter - RPC_INVALID_ADDRESS_OR_KEY = -5, // Invalid address or key - RPC_OUT_OF_MEMORY = -7, // Ran out of memory during operation - RPC_INVALID_PARAMETER = -8, // Invalid, missing or duplicate parameter - RPC_DATABASE_ERROR = -20, // Database error - RPC_DESERIALIZATION_ERROR = -22, // Error parsing or validating structure in raw format - RPC_VERIFY_ERROR = -25, // General error during transaction or block submission - RPC_VERIFY_REJECTED = -26, // Transaction or block was rejected by network rules - RPC_VERIFY_ALREADY_IN_CHAIN = -27, // Transaction already in chain - RPC_IN_WARMUP = -28, // Client still warming up + //! General application defined errors + RPC_MISC_ERROR = -1, //! std::exception thrown in command handling + RPC_FORBIDDEN_BY_SAFE_MODE = -2, //! Server is in safe mode, and command is not allowed in safe mode + RPC_TYPE_ERROR = -3, //! Unexpected type was passed as parameter + RPC_INVALID_ADDRESS_OR_KEY = -5, //! Invalid address or key + RPC_OUT_OF_MEMORY = -7, //! Ran out of memory during operation + RPC_INVALID_PARAMETER = -8, //! Invalid, missing or duplicate parameter + RPC_DATABASE_ERROR = -20, //! Database error + RPC_DESERIALIZATION_ERROR = -22, //! Error parsing or validating structure in raw format + RPC_VERIFY_ERROR = -25, //! General error during transaction or block submission + RPC_VERIFY_REJECTED = -26, //! Transaction or block was rejected by network rules + RPC_VERIFY_ALREADY_IN_CHAIN = -27, //! Transaction already in chain + RPC_IN_WARMUP = -28, //! Client still warming up - // Aliases for backward compatibility + //! Aliases for backward compatibility RPC_TRANSACTION_ERROR = RPC_VERIFY_ERROR, RPC_TRANSACTION_REJECTED = RPC_VERIFY_REJECTED, RPC_TRANSACTION_ALREADY_IN_CHAIN= RPC_VERIFY_ALREADY_IN_CHAIN, - // P2P client errors - RPC_CLIENT_NOT_CONNECTED = -9, // Bitcoin is not connected - RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, // Still downloading initial blocks - RPC_CLIENT_NODE_ALREADY_ADDED = -23, // Node is already added - RPC_CLIENT_NODE_NOT_ADDED = -24, // Node has not been added before + //! P2P client errors + RPC_CLIENT_NOT_CONNECTED = -9, //! Bitcoin is not connected + RPC_CLIENT_IN_INITIAL_DOWNLOAD = -10, //! Still downloading initial blocks + RPC_CLIENT_NODE_ALREADY_ADDED = -23, //! Node is already added + RPC_CLIENT_NODE_NOT_ADDED = -24, //! Node has not been added before - // Wallet errors - RPC_WALLET_ERROR = -4, // Unspecified problem with wallet (key not found etc.) - RPC_WALLET_INSUFFICIENT_FUNDS = -6, // Not enough funds in wallet or account - RPC_WALLET_INVALID_ACCOUNT_NAME = -11, // Invalid account name - RPC_WALLET_KEYPOOL_RAN_OUT = -12, // Keypool ran out, call keypoolrefill first - RPC_WALLET_UNLOCK_NEEDED = -13, // Enter the wallet passphrase with walletpassphrase first - RPC_WALLET_PASSPHRASE_INCORRECT = -14, // The wallet passphrase entered was incorrect - RPC_WALLET_WRONG_ENC_STATE = -15, // Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) - RPC_WALLET_ENCRYPTION_FAILED = -16, // Failed to encrypt the wallet - RPC_WALLET_ALREADY_UNLOCKED = -17, // Wallet is already unlocked + //! Wallet errors + RPC_WALLET_ERROR = -4, //! Unspecified problem with wallet (key not found etc.) + RPC_WALLET_INSUFFICIENT_FUNDS = -6, //! Not enough funds in wallet or account + RPC_WALLET_INVALID_ACCOUNT_NAME = -11, //! Invalid account name + RPC_WALLET_KEYPOOL_RAN_OUT = -12, //! Keypool ran out, call keypoolrefill first + RPC_WALLET_UNLOCK_NEEDED = -13, //! Enter the wallet passphrase with walletpassphrase first + RPC_WALLET_PASSPHRASE_INCORRECT = -14, //! The wallet passphrase entered was incorrect + RPC_WALLET_WRONG_ENC_STATE = -15, //! Command given in wrong wallet encryption state (encrypting an encrypted wallet etc.) + RPC_WALLET_ENCRYPTION_FAILED = -16, //! Failed to encrypt the wallet + RPC_WALLET_ALREADY_UNLOCKED = -17, //! Wallet is already unlocked }; -// -// IOStream device that speaks SSL but can also speak non-SSL -// +/** + * IOStream device that speaks SSL but can also speak non-SSL + */ template <typename Protocol> class SSLIOStreamDevice : public boost::iostreams::device<boost::iostreams::bidirectional> { public: diff --git a/src/rpcrawtransaction.cpp b/src/rpcrawtransaction.cpp index d3ce3b3191..25734f4930 100644 --- a/src/rpcrawtransaction.cpp +++ b/src/rpcrawtransaction.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "base58.h" diff --git a/src/rpcserver.cpp b/src/rpcserver.cpp index 01005c1cee..7022c50375 100644 --- a/src/rpcserver.cpp +++ b/src/rpcserver.cpp @@ -565,13 +565,8 @@ void StartRPCThreads() { unsigned char rand_pwd[32]; GetRandBytes(rand_pwd, 32); - string strWhatAmI = "To use bitcoind"; - if (mapArgs.count("-server")) - strWhatAmI = strprintf(_("To use the %s option"), "\"-server\""); - else if (mapArgs.count("-daemon")) - strWhatAmI = strprintf(_("To use the %s option"), "\"-daemon\""); uiInterface.ThreadSafeMessageBox(strprintf( - _("%s, you must set a rpcpassword in the configuration file:\n" + _("To use bitcoind, or the -server option to bitcoin-qt, you must set an rpcpassword in the configuration file:\n" "%s\n" "It is recommended you use the following random password:\n" "rpcuser=bitcoinrpc\n" @@ -581,7 +576,6 @@ void StartRPCThreads() "If the file does not exist, create it with owner-readable-only file permissions.\n" "It is also recommended to set alertnotify so you are notified of problems;\n" "for example: alertnotify=echo %%s | mail -s \"Bitcoin Alert\" admin@foo.com\n"), - strWhatAmI, GetConfigFile().string(), EncodeBase58(&rand_pwd[0],&rand_pwd[0]+32)), "", CClientUIInterface::MSG_ERROR | CClientUIInterface::SECURE); diff --git a/src/rpcserver.h b/src/rpcserver.h index b3234f65f2..7395fc23c6 100644 --- a/src/rpcserver.h +++ b/src/rpcserver.h @@ -40,12 +40,13 @@ void StartRPCThreads(); * If real RPC threads have already been started this is a no-op. */ void StartDummyRPCThread(); -/* Stop RPC threads */ +/** Stop RPC threads */ void StopRPCThreads(); -/* Query whether RPC is running */ +/** Query whether RPC is running */ bool IsRPCRunning(); -/* Set the RPC warmup status. When this is done, all RPC calls will error out +/** + * Set the RPC warmup status. When this is done, all RPC calls will error out * immediately with RPC_IN_WARMUP. */ void SetRPCWarmupStatus(const std::string& newStatus); diff --git a/src/rpcwallet.cpp b/src/rpcwallet.cpp index 4d9e5ea137..d2d14ad9f4 100644 --- a/src/rpcwallet.cpp +++ b/src/rpcwallet.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "amount.h" diff --git a/src/script/bitcoinconsensus.cpp b/src/script/bitcoinconsensus.cpp new file mode 100644 index 0000000000..4faa760ad7 --- /dev/null +++ b/src/script/bitcoinconsensus.cpp @@ -0,0 +1,91 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "bitcoinconsensus.h" + +#include "core/transaction.h" +#include "script/interpreter.h" +#include "version.h" + +namespace { + +/** A class that deserializes a single CTransaction one time. */ +class TxInputStream +{ +public: + TxInputStream(int nTypeIn, int nVersionIn, const unsigned char *txTo, size_t txToLen) : + m_type(nTypeIn), + m_version(nVersionIn), + m_data(txTo), + m_remaining(txToLen) + {} + + TxInputStream& read(char* pch, size_t nSize) + { + if (nSize > m_remaining) + throw std::ios_base::failure(std::string(__func__) + ": end of data"); + + if (pch == NULL) + throw std::ios_base::failure(std::string(__func__) + ": bad destination buffer"); + + if (m_data == NULL) + throw std::ios_base::failure(std::string(__func__) + ": bad source buffer"); + + memcpy(pch, m_data, nSize); + m_remaining -= nSize; + m_data += nSize; + return *this; + } + + template<typename T> + TxInputStream& operator>>(T& obj) + { + ::Unserialize(*this, obj, m_type, m_version); + return *this; + } + +private: + const int m_type; + const int m_version; + const unsigned char* m_data; + size_t m_remaining; +}; + +inline int set_error(bitcoinconsensus_error* ret, bitcoinconsensus_error serror) +{ + if (ret) + *ret = serror; + return 0; +} + +} // anon namespace + +int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char *txTo , unsigned int txToLen, + unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err) +{ + try { + TxInputStream stream(SER_NETWORK, PROTOCOL_VERSION, txTo, txToLen); + CTransaction tx; + stream >> tx; + if (nIn >= tx.vin.size()) + return set_error(err, bitcoinconsensus_ERR_TX_INDEX); + if (tx.GetSerializeSize(SER_NETWORK, PROTOCOL_VERSION) != txToLen) + return set_error(err, bitcoinconsensus_ERR_TX_SIZE_MISMATCH); + + // Regardless of the verification result, the tx did not error. + set_error(err, bitcoinconsensus_ERR_OK); + + return VerifyScript(tx.vin[nIn].scriptSig, CScript(scriptPubKey, scriptPubKey + scriptPubKeyLen), flags, SignatureChecker(tx, nIn), NULL); + } catch (std::exception &e) { + return set_error(err, bitcoinconsensus_ERR_TX_DESERIALIZE); // Error deserializing + } +} + +unsigned int bitcoinconsensus_version() +{ + // Just use the API version for now + return BITCOINCONSENSUS_API_VER; +} diff --git a/src/script/bitcoinconsensus.h b/src/script/bitcoinconsensus.h new file mode 100644 index 0000000000..15e3337a8d --- /dev/null +++ b/src/script/bitcoinconsensus.h @@ -0,0 +1,67 @@ +// Copyright (c) 2009-2010 Satoshi Nakamoto +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_BITCOINCONSENSUS_H +#define BITCOIN_BITCOINCONSENSUS_H + +#if defined(BUILD_BITCOIN_INTERNAL) && defined(HAVE_CONFIG_H) +#include "config/bitcoin-config.h" + #if defined(_WIN32) + #if defined(DLL_EXPORT) + #if defined(HAVE_FUNC_ATTRIBUTE_DLLEXPORT) + #define EXPORT_SYMBOL __declspec(dllexport) + #else + #define EXPORT_SYMBOL + #endif + #endif + #elif defined(HAVE_FUNC_ATTRIBUTE_VISIBILITY) + #define EXPORT_SYMBOL __attribute__ ((visibility ("default"))) + #endif +#elif defined(MSC_VER) && !defined(STATIC_LIBBITCOINCONSENSUS) + #define EXPORT_SYMBOL __declspec(dllimport) +#endif + +#ifndef EXPORT_SYMBOL + #define EXPORT_SYMBOL +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#define BITCOINCONSENSUS_API_VER 0 + +typedef enum bitcoinconsensus_error_t +{ + bitcoinconsensus_ERR_OK = 0, + bitcoinconsensus_ERR_TX_INDEX, + bitcoinconsensus_ERR_TX_SIZE_MISMATCH, + bitcoinconsensus_ERR_TX_DESERIALIZE, +} bitcoinconsensus_error; + +/** Script verification flags */ +enum +{ + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_NONE = 0, + bitcoinconsensus_SCRIPT_FLAGS_VERIFY_P2SH = (1U << 0), // evaluate P2SH (BIP16) subscripts +}; + +/// Returns 1 if the input nIn of the serialized transaction pointed to by +/// txTo correctly spends the scriptPubKey pointed to by scriptPubKey under +/// the additional constraints specified by flags. +/// If not NULL, err will contain an error/success code for the operation +EXPORT_SYMBOL int bitcoinconsensus_verify_script(const unsigned char *scriptPubKey, unsigned int scriptPubKeyLen, + const unsigned char *txTo , unsigned int txToLen, + unsigned int nIn, unsigned int flags, bitcoinconsensus_error* err); + +EXPORT_SYMBOL unsigned int bitcoinconsensus_version(); + +#ifdef __cplusplus +} // extern "C" +#endif + +#undef EXPORT_SYMBOL + +#endif // BITCOIN_BITCOINCONSENSUS_H diff --git a/src/script/interpreter.cpp b/src/script/interpreter.cpp index cf81fe30a2..5eda23731d 100644 --- a/src/script/interpreter.cpp +++ b/src/script/interpreter.cpp @@ -207,9 +207,9 @@ bool static CheckSignatureEncoding(const valtype &vchSig, unsigned int flags, Sc return true; } -bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags) { +bool static CheckPubKeyEncoding(const valtype &vchSig, unsigned int flags, ScriptError* serror) { if ((flags & SCRIPT_VERIFY_STRICTENC) != 0 && !IsCompressedOrUncompressedPubKey(vchSig)) { - return false; + return set_error(serror, SCRIPT_ERR_PUBKEYTYPE); } return true; } @@ -329,8 +329,14 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un // Control // case OP_NOP: + break; + case OP_NOP1: case OP_NOP2: case OP_NOP3: case OP_NOP4: case OP_NOP5: case OP_NOP6: case OP_NOP7: case OP_NOP8: case OP_NOP9: case OP_NOP10: + { + if (flags & SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS) + return set_error(serror, SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS); + } break; case OP_IF: @@ -786,11 +792,11 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un // Drop the signature, since there's no way for a signature to sign itself scriptCode.FindAndDelete(CScript(vchSig)); - if (!CheckSignatureEncoding(vchSig, flags, serror)) { + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { //serror is set return false; } - bool fSuccess = CheckPubKeyEncoding(vchPubKey, flags) && checker.CheckSig(vchSig, vchPubKey, scriptCode); + bool fSuccess = checker.CheckSig(vchSig, vchPubKey, scriptCode); popstack(stack); popstack(stack); @@ -849,13 +855,16 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un valtype& vchSig = stacktop(-isig); valtype& vchPubKey = stacktop(-ikey); - if (!CheckSignatureEncoding(vchSig, flags, serror)) { + // Note how this makes the exact order of pubkey/signature evaluation + // distinguishable by CHECKMULTISIG NOT if the STRICTENC flag is set. + // See the script_(in)valid tests for details. + if (!CheckSignatureEncoding(vchSig, flags, serror) || !CheckPubKeyEncoding(vchPubKey, flags, serror)) { // serror is set return false; } // Check signature - bool fOk = CheckPubKeyEncoding(vchPubKey, flags) && checker.CheckSig(vchSig, vchPubKey, scriptCode); + bool fOk = checker.CheckSig(vchSig, vchPubKey, scriptCode); if (fOk) { isig++; @@ -865,7 +874,8 @@ bool EvalScript(vector<vector<unsigned char> >& stack, const CScript& script, un nKeysCount--; // If there are more signatures left than keys left, - // then too many signatures have failed + // then too many signatures have failed. Exit early, + // without checking any further signatures. if (nSigsCount > nKeysCount) fSuccess = false; } diff --git a/src/script/interpreter.h b/src/script/interpreter.h index 14cccc558f..35b2f6c65a 100644 --- a/src/script/interpreter.h +++ b/src/script/interpreter.h @@ -35,8 +35,8 @@ enum SCRIPT_VERIFY_P2SH = (1U << 0), // Passing a non-strict-DER signature or one with undefined hashtype to a checksig operation causes script failure. - // Passing a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) to checksig causes that pubkey to be - // skipped (not softfork safe: this flag can widen the validity of OP_CHECKSIG OP_NOT). + // Evaluating a pubkey that is not (0x04 + 64 bytes) or (0x02 or 0x03 + 32 bytes) by checksig causes script failure. + // (softfork safe, but not used or intended as a consensus rule). SCRIPT_VERIFY_STRICTENC = (1U << 1), // Passing a non-strict-DER signature to a checksig operation causes script failure (softfork safe, BIP62 rule 1) @@ -57,7 +57,18 @@ enum // any other push causes the script to fail (BIP62 rule 3). // In addition, whenever a stack element is interpreted as a number, it must be of minimal length (BIP62 rule 4). // (softfork safe) - SCRIPT_VERIFY_MINIMALDATA = (1U << 6) + SCRIPT_VERIFY_MINIMALDATA = (1U << 6), + + // Discourage use of NOPs reserved for upgrades (NOP1-10) + // + // Provided so that nodes can avoid accepting or mining transactions + // containing executed NOP's whose meaning may change after a soft-fork, + // thus rendering the script invalid; with this flag set executing + // discouraged NOPs fails the script. This verification flag will never be + // a mandatory flag applied to scripts in a block. NOPs that are not + // executed, e.g. within an unexecuted IF ENDIF block, are *not* rejected. + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS = (1U << 7) + }; uint256 SignatureHash(const CScript &scriptCode, const CTransaction& txTo, unsigned int nIn, int nHashType); diff --git a/src/script/script_error.cpp b/src/script/script_error.cpp index 4a3df268ec..5d24ed98ba 100644 --- a/src/script/script_error.cpp +++ b/src/script/script_error.cpp @@ -59,6 +59,10 @@ const char* ScriptErrorString(const ScriptError serror) return "Non-canonical signature: S value is unnecessarily high"; case SCRIPT_ERR_SIG_NULLDUMMY: return "Dummy CHECKMULTISIG argument must be zero"; + case SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS: + return "NOPx reserved for soft-fork upgrades"; + case SCRIPT_ERR_PUBKEYTYPE: + return "Public key is neither compressed or uncompressed"; case SCRIPT_ERR_UNKNOWN_ERROR: case SCRIPT_ERR_ERROR_COUNT: default: break; diff --git a/src/script/script_error.h b/src/script/script_error.h index ae6626b257..ac1f2deae5 100644 --- a/src/script/script_error.h +++ b/src/script/script_error.h @@ -42,6 +42,10 @@ typedef enum ScriptError_t SCRIPT_ERR_SIG_PUSHONLY, SCRIPT_ERR_SIG_HIGH_S, SCRIPT_ERR_SIG_NULLDUMMY, + SCRIPT_ERR_PUBKEYTYPE, + + /* softfork safeness */ + SCRIPT_ERR_DISCOURAGE_UPGRADABLE_NOPS, SCRIPT_ERR_ERROR_COUNT } ScriptError; diff --git a/src/script/standard.h b/src/script/standard.h index f3dcc75fdc..c4b82b4c45 100644 --- a/src/script/standard.h +++ b/src/script/standard.h @@ -47,7 +47,8 @@ static const unsigned int MANDATORY_SCRIPT_VERIFY_FLAGS = SCRIPT_VERIFY_P2SH; static const unsigned int STANDARD_SCRIPT_VERIFY_FLAGS = MANDATORY_SCRIPT_VERIFY_FLAGS | SCRIPT_VERIFY_STRICTENC | SCRIPT_VERIFY_MINIMALDATA | - SCRIPT_VERIFY_NULLDUMMY; + SCRIPT_VERIFY_NULLDUMMY | + SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS; /** For convenience, standard but not mandatory verify flags. */ static const unsigned int STANDARD_NOT_MANDATORY_VERIFY_FLAGS = STANDARD_SCRIPT_VERIFY_FLAGS & ~MANDATORY_SCRIPT_VERIFY_FLAGS; diff --git a/src/test/data/script_invalid.json b/src/test/data/script_invalid.json index 6f451a36ee..71e757714c 100644 --- a/src/test/data/script_invalid.json +++ b/src/test/data/script_invalid.json @@ -163,6 +163,23 @@ nSequences are max. ["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 2 EQUAL", "P2SH,STRICTENC"], ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_11' EQUAL", "P2SH,STRICTENC"], +["Ensure 100% coverage of discouraged NOPS"], +["1", "NOP1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP2", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP3", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP4", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP5", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP6", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP7", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP8", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP9", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], +["1", "NOP10", "P2SH,DISCOURAGE_UPGRADABLE_NOPS"], + +["NOP10", "1", "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in scriptSig"], + +["1 0x01 0xb9", "HASH160 0x14 0x15727299b05b45fdaf9ac9ecf7565cfe27c3e567 EQUAL", + "P2SH,DISCOURAGE_UPGRADABLE_NOPS", "Discouraged NOP10 in redeemScript"], + ["0x50","1", "P2SH,STRICTENC", "opcode 0x50 is reserved"], ["1", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"], ["1", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"], @@ -576,11 +593,48 @@ nSequences are max. "P2PK NOT with hybrid pubkey but no STRICTENC" ], [ + "0x47 0x3044022078033e4227aa05ded69d8da579966578e230d8a7fb44d5f1a0620c3853c24f78022006a2e3f4d872ac8dfdc529110aa37301d65a76255a4b6cce2992adacd4d2c4e201", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "STRICTENC", + "P2PK NOT with hybrid pubkey" +], +[ + "0x47 0x304402207592427de20e315d644839754f2a5cca5b978b983a15e6da82109ede01722baa022032ceaf78590faa3f7743821e1b47b897ed1a57f6ee1c8a7519d23774d8de3c4401", + "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "STRICTENC", + "P2PK NOT with invalid hybrid pubkey" +], +[ + "0 0x47 0x304402206797289d3dc81692edae58430276d04641ea5d86967be557163f8494da32fd78022006fc6ab77aaed4ac11ea69cd878ab26e3e24290f47a43e9adf34075d52b7142c01", + "1 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 2 CHECKMULTISIG", + "STRICTENC", + "1-of-2 with the first 1 hybrid pubkey" +], +[ "0x47 0x304402201f82b99a813c9c48c8dee8d2c43b8f637b72353fe9bdcc084537bc17e2ab770402200c43b96a5f7e115f0114eabda32e068145965cb6c7b5ef64833bb4fcf9fc1b3b05", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", "STRICTENC", "P2PK with undefined hashtype" ], + +[" +Order of CHECKMULTISIG evaluation tests, inverted by swapping the order of +pubkeys/signatures so they fail due to the STRICTENC rules on validly encoded +signatures and pubkeys. +"], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with the first pubkey invalid, and both signatures validly encoded." +], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but first signature invalid." +], + [ "0x47 0x30440220166848cd5b82a32b5944d90de3c35249354b43773c2ece1844ee8d1103e2f6c602203b6b046da4243c77adef80ada9201b27bbfdf7f9d5428f40434b060432afd62005", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG NOT", diff --git a/src/test/data/script_valid.json b/src/test/data/script_valid.json index 439c82ef32..ada45a64ed 100644 --- a/src/test/data/script_valid.json +++ b/src/test/data/script_valid.json @@ -235,6 +235,11 @@ nSequences are max. ["1","NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10 1 EQUAL", "P2SH,STRICTENC"], ["'NOP_1_to_10' NOP1 NOP2 NOP3 NOP4 NOP5 NOP6 NOP7 NOP8 NOP9 NOP10","'NOP_1_to_10' EQUAL", "P2SH,STRICTENC"], +["1", "NOP", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", "Discourage NOPx flag allows OP_NOP"], + +["0", "IF NOP10 ENDIF 1", "P2SH,STRICTENC,DISCOURAGE_UPGRADABLE_NOPS", + "Discouraged NOPs are allowed if not executed"], + ["0", "IF 0xba ELSE 1 ENDIF", "P2SH,STRICTENC", "opcodes above NOP10 invalid if executed"], ["0", "IF 0xbb ELSE 1 ENDIF", "P2SH,STRICTENC"], ["0", "IF 0xbc ELSE 1 ENDIF", "P2SH,STRICTENC"], @@ -739,23 +744,48 @@ nSequences are max. "P2PK with hybrid pubkey but no STRICTENC" ], [ - "0x47 0x3044022078033e4227aa05ded69d8da579966578e230d8a7fb44d5f1a0620c3853c24f78022006a2e3f4d872ac8dfdc529110aa37301d65a76255a4b6cce2992adacd4d2c4e201", - "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", - "STRICTENC", - "P2PK NOT with hybrid pubkey" -], -[ "0x47 0x3044022078d6c447887e88dcbe1bc5b613645280df6f4e5935648bc226e9d91da71b3216022047d6b7ef0949b228fc1b359afb8d50500268711354298217b983c26970790c7601", "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", "", "P2PK NOT with invalid hybrid pubkey but no STRICTENC" ], [ - "0x47 0x304402207592427de20e315d644839754f2a5cca5b978b983a15e6da82109ede01722baa022032ceaf78590faa3f7743821e1b47b897ed1a57f6ee1c8a7519d23774d8de3c4401", - "0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 CHECKSIG NOT", + "0 0x47 0x304402203b269b9fbc0936877bf855b5fb41757218d9548b246370d991442a5f5bd1c3440220235268a4eaa8c67e543c6e37da81dd36d3b1be2de6b4fef04113389ca6ddc04501", + "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", + "", + "1-of-2 with the second 1 hybrid pubkey and no STRICTENC" +], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "1 0x41 0x0679be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 0x21 0x038282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f51508 2 CHECKMULTISIG", "STRICTENC", - "P2PK NOT with invalid hybrid pubkey" + "1-of-2 with the second 1 hybrid pubkey" ], + +[" +CHECKMULTISIG evaluation order tests. CHECKMULTISIG evaluates signatures and +pubkeys in a specific order, and will exit early if the number of signatures +left to check is greater than the number of keys left. As STRICTENC fails the +script when it reaches an invalidly encoded signature or pubkey, we can use it +to test the exact order in which signatures and pubkeys are evaluated by +distinguishing CHECKMULTISIG returning false on the stack and the script as a +whole failing. + +See also the corresponding inverted versions of these tests in script_invalid.json +"], +[ + "0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "2 0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with the second pubkey invalid, and both signatures validly encoded. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid pubkey." +], +[ + "0 0 0x47 0x3044022044dc17b0887c161bb67ba9635bf758735bdde503e4b0a0987f587f14a4e1143d022009a215772d49a85dae40d8ca03955af26ad3978a0ff965faa12915e9586249a501", + "2 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 0x21 0x02865c40293a680cb9c020e7b1e106d8c1916d3cef99aa431a56d253e69256dac0 2 CHECKMULTISIG NOT", + "STRICTENC", + "2-of-2 CHECKMULTISIG NOT with both pubkeys valid, but second signature invalid. Valid pubkey fails, and CHECKMULTISIG exits early, prior to evaluation of second invalid signature." +], + [ "0x47 0x304402204649e9517ef0377a8f8270bd423053fd98ddff62d74ea553e9579558abbb75e4022044a2b2344469c12e35ed898987711272b634733dd0f5e051288eceb04bd4669e05", "0x41 0x048282263212c609d9ea2a6e3e172de238d8c39cabd5ac1ca10646e23fd5f5150811f8a8098557dfe45e8256e830b60ace62d613ac2f7b17bed31b6eaff6e26caf CHECKSIG", diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index b32f3774fe..f9e35e0166 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -82,6 +82,26 @@ BOOST_AUTO_TEST_CASE(key_test1) CPubKey pubkey1C = key1C.GetPubKey(); CPubKey pubkey2C = key2C.GetPubKey(); + BOOST_CHECK(key1.VerifyPubKey(pubkey1)); + BOOST_CHECK(!key1.VerifyPubKey(pubkey1C)); + BOOST_CHECK(!key1.VerifyPubKey(pubkey2)); + BOOST_CHECK(!key1.VerifyPubKey(pubkey2C)); + + BOOST_CHECK(!key1C.VerifyPubKey(pubkey1)); + BOOST_CHECK(key1C.VerifyPubKey(pubkey1C)); + BOOST_CHECK(!key1C.VerifyPubKey(pubkey2)); + BOOST_CHECK(!key1C.VerifyPubKey(pubkey2C)); + + BOOST_CHECK(!key2.VerifyPubKey(pubkey1)); + BOOST_CHECK(!key2.VerifyPubKey(pubkey1C)); + BOOST_CHECK(key2.VerifyPubKey(pubkey2)); + BOOST_CHECK(!key2.VerifyPubKey(pubkey2C)); + + BOOST_CHECK(!key2C.VerifyPubKey(pubkey1)); + BOOST_CHECK(!key2C.VerifyPubKey(pubkey1C)); + BOOST_CHECK(!key2C.VerifyPubKey(pubkey2)); + BOOST_CHECK(key2C.VerifyPubKey(pubkey2C)); + BOOST_CHECK(addr1.Get() == CTxDestination(pubkey1.GetID())); BOOST_CHECK(addr2.Get() == CTxDestination(pubkey2.GetID())); BOOST_CHECK(addr1C.Get() == CTxDestination(pubkey1C.GetID())); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 9a31bdf5fd..53c2e7b261 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -57,6 +57,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) uint256 hash; LOCK(cs_main); + Checkpoints::fEnabled = false; // Simple block creation, nothing special yet: BOOST_CHECK(pblocktemplate = CreateNewBlock(scriptPubKey)); @@ -259,6 +260,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_FOREACH(CTransaction *tx, txFirst) delete tx; + Checkpoints::fEnabled = true; } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index d98154571b..6952f4c584 100644 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -14,6 +14,10 @@ #include "script/sign.h" #include "util.h" +#if defined(HAVE_CONSENSUS_LIB) +#include "script/bitcoinconsensus.h" +#endif + #include <fstream> #include <stdint.h> #include <string> @@ -94,8 +98,15 @@ CMutableTransaction BuildSpendingTransaction(const CScript& scriptSig, const CMu void DoTest(const CScript& scriptPubKey, const CScript& scriptSig, int flags, bool expect, const std::string& message) { ScriptError err; - BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)), 0), &err) == expect, message); + CMutableTransaction tx = BuildSpendingTransaction(scriptSig, BuildCreditingTransaction(scriptPubKey)); + CMutableTransaction tx2 = tx; + BOOST_CHECK_MESSAGE(VerifyScript(scriptSig, scriptPubKey, flags, SignatureChecker(tx, 0), &err) == expect, message); BOOST_CHECK_MESSAGE(expect == (err == SCRIPT_ERR_OK), std::string(ScriptErrorString(err)) + ": " + message); +#if defined(HAVE_CONSENSUS_LIB) + CDataStream stream(SER_NETWORK, PROTOCOL_VERSION); + stream << tx2; + BOOST_CHECK_MESSAGE(bitcoinconsensus_verify_script(begin_ptr(scriptPubKey), scriptPubKey.size(), (const unsigned char*)&stream[0], stream.size(), 0, flags, NULL) == expect,message); +#endif } void static NegateSignatureS(std::vector<unsigned char>& vchSig) { @@ -417,15 +428,24 @@ BOOST_AUTO_TEST_CASE(script_build) bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, "P2PK NOT with hybrid pubkey but no STRICTENC", 0 ).PushSig(keys.key0, SIGHASH_ALL)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, "P2PK NOT with invalid hybrid pubkey but no STRICTENC", 0 ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); - good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, - "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC - ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); + bad.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey0H) << OP_CHECKSIG << OP_NOT, + "P2PK NOT with invalid hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).PushSig(keys.key0, SIGHASH_ALL).DamagePush(10)); + good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the second 1 hybrid pubkey and no STRICTENC", 0 + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + good.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey0H) << ToByteVector(keys.pubkey1C) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the second 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); + bad.push_back(TestBuilder(CScript() << OP_1 << ToByteVector(keys.pubkey1C) << ToByteVector(keys.pubkey0H) << OP_2 << OP_CHECKMULTISIG, + "1-of-2 with the first 1 hybrid pubkey", SCRIPT_VERIFY_STRICTENC + ).Num(0).PushSig(keys.key1, SIGHASH_ALL)); good.push_back(TestBuilder(CScript() << ToByteVector(keys.pubkey1) << OP_CHECKSIG, "P2PK with undefined hashtype but no STRICTENC", 0 diff --git a/src/test/transaction_tests.cpp b/src/test/transaction_tests.cpp index bf3a60c04f..e939e89972 100644 --- a/src/test/transaction_tests.cpp +++ b/src/test/transaction_tests.cpp @@ -37,7 +37,8 @@ static std::map<string, unsigned int> mapFlagNames = boost::assign::map_list_of (string("LOW_S"), (unsigned int)SCRIPT_VERIFY_LOW_S) (string("SIGPUSHONLY"), (unsigned int)SCRIPT_VERIFY_SIGPUSHONLY) (string("MINIMALDATA"), (unsigned int)SCRIPT_VERIFY_MINIMALDATA) - (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY); + (string("NULLDUMMY"), (unsigned int)SCRIPT_VERIFY_NULLDUMMY) + (string("DISCOURAGE_UPGRADABLE_NOPS"), (unsigned int)SCRIPT_VERIFY_DISCOURAGE_UPGRADABLE_NOPS); unsigned int ParseScriptFlags(string strFlags) { diff --git a/src/timedata.cpp b/src/timedata.cpp index 40cdb33f7a..59f7778db1 100644 --- a/src/timedata.cpp +++ b/src/timedata.cpp @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "timedata.h" @@ -17,14 +17,13 @@ using namespace std; static CCriticalSection cs_nTimeOffset; static int64_t nTimeOffset = 0; -// -// "Never go to sea with two chronometers; take one or three." -// Our three time sources are: -// - System clock -// - Median of other nodes clocks -// - The user (asking the user to fix the system clock if the first two disagree) -// -// +/** + * "Never go to sea with two chronometers; take one or three." + * Our three time sources are: + * - System clock + * - Median of other nodes clocks + * - The user (asking the user to fix the system clock if the first two disagree) + */ int64_t GetTimeOffset() { LOCK(cs_nTimeOffset); diff --git a/src/timedata.h b/src/timedata.h index 2c20f4efd5..64595ffc37 100644 --- a/src/timedata.h +++ b/src/timedata.h @@ -1,5 +1,5 @@ // Copyright (c) 2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_TIMEDATA_H @@ -12,7 +12,8 @@ class CNetAddr; -/** Median filter over a stream of values. +/** + * Median filter over a stream of values. * Returns the median of the last N numbers */ template <typename T> @@ -67,7 +68,7 @@ public: } }; -/* Functions to keep track of adjusted P2P time */ +/** Functions to keep track of adjusted P2P time */ int64_t GetTimeOffset(); int64_t GetAdjustedTime(); void AddTimeData(const CNetAddr& ip, int64_t nTime); diff --git a/src/txdb.h b/src/txdb.h index 147c186990..9a98fcc41b 100644 --- a/src/txdb.h +++ b/src/txdb.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto -// Copyright (c) 2009-2013 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Copyright (c) 2009-2014 The Bitcoin developers +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_TXDB_H @@ -17,11 +17,11 @@ class CCoins; class uint256; -// -dbcache default (MiB) +//! -dbcache default (MiB) static const int64_t nDefaultDbCache = 100; -// max. -dbcache in (MiB) +//! max. -dbcache in (MiB) static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 4096 : 1024; -// min. -dbcache in (MiB) +//! min. -dbcache in (MiB) static const int64_t nMinDbCache = 4; /** CCoinsView backed by the LevelDB coin database (chainstate/) */ diff --git a/src/uint256.h b/src/uint256.h index 28de540226..56f7f44a16 100644 --- a/src/uint256.h +++ b/src/uint256.h @@ -1,6 +1,6 @@ // Copyright (c) 2009-2010 Satoshi Nakamoto // Copyright (c) 2009-2014 The Bitcoin developers -// Distributed under the MIT/X11 software license, see the accompanying +// Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. #ifndef BITCOIN_UINT256_H @@ -255,8 +255,10 @@ public: return sizeof(pn); } - // Returns the position of the highest bit set plus one, or zero if the - // value is zero. + /** + * Returns the position of the highest bit set plus one, or zero if the + * value is zero. + */ unsigned int bits() const; uint64_t GetLow64() const @@ -301,26 +303,27 @@ public: uint256(uint64_t b) : base_uint<256>(b) {} explicit uint256(const std::string& str) : base_uint<256>(str) {} explicit uint256(const std::vector<unsigned char>& vch) : base_uint<256>(vch) {} - - // The "compact" format is a representation of a whole - // number N using an unsigned 32bit number similar to a - // floating point format. - // The most significant 8 bits are the unsigned exponent of base 256. - // This exponent can be thought of as "number of bytes of N". - // The lower 23 bits are the mantissa. - // Bit number 24 (0x800000) represents the sign of N. - // N = (-1^sign) * mantissa * 256^(exponent-3) - // - // Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). - // MPI uses the most significant bit of the first byte as sign. - // Thus 0x1234560000 is compact (0x05123456) - // and 0xc0de000000 is compact (0x0600c0de) - // (0x05c0de00) would be -0x40de000000 - // - // Bitcoin only uses this "compact" format for encoding difficulty - // targets, which are unsigned 256bit quantities. Thus, all the - // complexities of the sign bit and using base 256 are probably an - // implementation accident. + + /** + * The "compact" format is a representation of a whole + * number N using an unsigned 32bit number similar to a + * floating point format. + * The most significant 8 bits are the unsigned exponent of base 256. + * This exponent can be thought of as "number of bytes of N". + * The lower 23 bits are the mantissa. + * Bit number 24 (0x800000) represents the sign of N. + * N = (-1^sign) * mantissa * 256^(exponent-3) + * + * Satoshi's original implementation used BN_bn2mpi() and BN_mpi2bn(). + * MPI uses the most significant bit of the first byte as sign. + * Thus 0x1234560000 is compact (0x05123456) + * and 0xc0de000000 is compact (0x0600c0de) + * + * Bitcoin only uses this "compact" format for encoding difficulty + * targets, which are unsigned 256bit quantities. Thus, all the + * complexities of the sign bit and using base 256 are probably an + * implementation accident. + */ uint256& SetCompact(uint32_t nCompact, bool *pfNegative = NULL, bool *pfOverflow = NULL); uint32_t GetCompact(bool fNegative = false) const; diff --git a/src/wallet.cpp b/src/wallet.cpp index 5aea9881cd..353010ae07 100644 --- a/src/wallet.cpp +++ b/src/wallet.cpp @@ -79,6 +79,7 @@ CPubKey CWallet::GenerateNewKey() SetMinVersion(FEATURE_COMPRPUBKEY); CPubKey pubkey = secret.GetPubKey(); + assert(secret.VerifyPubKey(pubkey)); // Create new metadata int64_t nCreationTime = GetTime(); |